ZQuest Classic Coverage Report


Directory: src/
File: src/zc/maps.cpp
Date: 2026-01-20 05:20:45
Exec Total Coverage
Lines: 4209 5244 80.3%
Functions: 294 333 88.3%
Branches: 3258 5330 61.1%

Line Branch Exec Source
1 #include "base/combo.h"
2 #include "base/handles.h"
3 #include "base/util.h"
4 #include "base/zdefs.h"
5 #include "base/general.h"
6 #include <cstring>
7 #include <assert.h>
8 #include <math.h>
9 #include <vector>
10 #include <deque>
11 #include <string>
12 #include <set>
13 #include <array>
14 #include <sstream>
15 using std::set;
16
17 #include "base/qrs.h"
18 #include "base/dmap.h"
19 #include "base/mapscr.h"
20 #include "base/misctypes.h"
21 #include "base/initdata.h"
22 #include "zc/maps.h"
23 #include "zc/zelda.h"
24 #include "zc/zc_ffc.h"
25 #include "tiles.h"
26 #include "sprite.h"
27 #include "gui/jwin.h"
28 #include "base/zsys.h"
29 #include "subscr.h"
30 #include "zc/zc_subscr.h"
31 #include "zc/hero.h"
32 #include "zc/guys.h"
33 #include "zc/ffscript.h"
34 #include "drawing.h"
35 #include "zc/combos.h"
36 #include "zc/replay.h"
37 #include "slopes.h"
38 #include "particles.h"
39 #include <fmt/format.h>
40 #include "zc/render.h"
41 #include "iter.h"
42 #include <ranges>
43
44 // All the temporary screens (and their layers) for the currently loaded map.
45 static mapscr* temporary_screens[136*7];
46 // Set by load_region.
47 static bool screen_in_current_region[136];
48 430 static rpos_handle_t current_region_rpos_handles[136*7];
49 static bool current_region_rpos_handles_dirty;
50 static int current_region_screen_count;
51 static std::pair<const rpos_handle_t*, int> current_region_rpos_handles_scr[136];
52
53 viewport_t viewport;
54 static int viewport_sprite_uid;
55 ViewportMode viewport_mode;
56 int world_w, world_h;
57 int region_scr_dx, region_scr_dy;
58 int region_scr_count;
59 rpos_t region_max_rpos;
60 int region_num_rpos;
61 region_t cur_region, scrolling_region;
62
63 430 maze_state_t maze_state;
64 int scrolling_maze_last_solved_screen;
65
66 613 void maps_init_game_vars()
67 {
68 613 viewport = {};
69 613 viewport_mode = ViewportMode::CenterAndBound;
70 613 viewport_sprite_uid = 1;
71 613 currscr_for_passive_subscr = -1;
72 613 }
73
74 static region_ids_t current_region_ids;
75
76 // Returns true if the (map, screen) is inside a scrolling region.
77 15148767 static bool is_in_scrolling_region(int map, int screen)
78 {
79 15148767 return get_region_id(map, screen) != 0;
80 }
81
82 bool is_in_screenscrolling_region(int screen)
83 {
84 if (!screenscrolling) return false;
85
86 int x = screen % 16;
87 int y = screen / 16;
88 return
89 scrolling_region.origin_screen_x >= x && scrolling_region.origin_screen_x < x + scrolling_region.screen_width &&
90 scrolling_region.origin_screen_y >= y && scrolling_region.origin_screen_y < y + scrolling_region.screen_height;
91 }
92
93 8992231820 bool is_in_scrolling_region()
94 {
95 8992231820 return cur_region.screen_count > 1;
96 }
97
98 2232 static bool is_same_region_id(int region_origin_scr, int map, int scr)
99 {
100
2/2
✓ Branch 0 taken 772 times.
✓ Branch 1 taken 1460 times.
2232 if (!is_in_scrolling_region(map, scr)) return false;
101 1460 int region_id = get_region_id(map, region_origin_scr);
102
1/2
✓ Branch 0 taken 1460 times.
✗ Branch 1 not taken.
1460 return region_id && region_id == get_region_id(map, scr);
103 2232 }
104
105 251460240 bool is_in_current_region(int map, int screen)
106 {
107
2/2
✓ Branch 0 taken 1598 times.
✓ Branch 1 taken 251458642 times.
251460240 if (map != cur_map)
108 1598 return false;
109
110
3/4
✓ Branch 0 taken 251458642 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 251446429 times.
✓ Branch 3 taken 12213 times.
251458642 if (screen >= 0 && screen < 128)
111 251446429 return screen_in_current_region[screen];
112
113 12213 return screen == cur_screen;
114 251460240 }
115
116 244778566 bool is_in_current_region(int screen)
117 {
118
5/6
✓ Branch 0 taken 243662948 times.
✓ Branch 1 taken 1115618 times.
✓ Branch 2 taken 1115618 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 1115613 times.
244778566 return screen == cur_screen || (screen >= 0 && screen < 128 && screen_in_current_region[screen]);
119 }
120
121 30808100 bool is_in_current_region(mapscr* scr)
122 {
123
2/2
✓ Branch 0 taken 14690 times.
✓ Branch 1 taken 30793410 times.
30808100 return scr->map == cur_map && is_in_current_region(scr->screen);
124 }
125
126 63793466 bool is_extended_height_mode()
127 {
128
2/2
✓ Branch 0 taken 63594018 times.
✓ Branch 1 taken 199448 times.
63793466 return cur_region.screen_height > 1 && (DMaps[cur_dmap].flags & dmfEXTENDEDVIEWPORT);
129 }
130
131 // Returns 0 if this is not a scrolling region.
132 42487559 int get_region_id(int map, int screen)
133 {
134
2/2
✓ Branch 0 taken 401435 times.
✓ Branch 1 taken 42086124 times.
42487559 if (screen >= 128) return 0;
135
2/2
✓ Branch 0 taken 42085000 times.
✓ Branch 1 taken 1124 times.
42086124 if (map == cur_region.map) return current_region_ids[screen];
136
137 1124 return Regions[map].get_region_id(screen);
138 42487559 }
139
140 27276802 int get_current_region_id()
141 {
142 27276802 return get_region_id(cur_map, cur_screen);
143 }
144
145 67250 void calculate_region(int map, int screen, region_t& region, int& region_scr_dx, int& region_scr_dy)
146 {
147 67250 region.map = map;
148
149
2/2
✓ Branch 0 taken 66976 times.
✓ Branch 1 taken 274 times.
67250 if (!is_in_scrolling_region(map, screen))
150 {
151 66976 region.region_id = 0;
152 66976 region.origin_screen = screen;
153 66976 region.origin_screen_x = screen % 16;
154 66976 region.origin_screen_y = screen / 16;
155 66976 region.screen_width = 1;
156 66976 region.screen_height = 1;
157 66976 region.screen_count = 1;
158 66976 region.width = 256;
159 66976 region.height = 176;
160 66976 region_scr_dx = 0;
161 66976 region_scr_dy = 0;
162 66976 return;
163 }
164
165 274 int input_scr_x = screen % 16;
166 274 int input_scr_y = screen / 16;
167
168 // For the given screen, find the top-left corner of its region.
169 274 int origin_scr_x = input_scr_x;
170 274 int origin_scr_y = input_scr_y;
171 274 int origin_scr = screen;
172
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 372 times.
434 while (origin_scr_x > 0)
173 {
174
2/2
✓ Branch 0 taken 212 times.
✓ Branch 1 taken 160 times.
372 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x - 1, origin_scr_y))) break;
175 160 origin_scr_x--;
176 }
177
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 414 times.
508 while (origin_scr_y > 0)
178 {
179
2/2
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 234 times.
414 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, origin_scr_y - 1))) break;
180 234 origin_scr_y--;
181 }
182 274 origin_scr = map_scr_xy_to_index(origin_scr_x, origin_scr_y);
183
184 // Now find the bottom-right corner.
185 274 int region_scr_right = origin_scr_x;
186
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 614 times.
642 while (region_scr_right < 15)
187 {
188
2/2
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 368 times.
614 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(region_scr_right + 1, origin_scr_y))) break;
189 368 region_scr_right++;
190 }
191 274 int region_scr_bottom = origin_scr_y;
192
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 832 times.
856 while (region_scr_bottom < 7)
193 {
194
2/2
✓ Branch 0 taken 250 times.
✓ Branch 1 taken 582 times.
832 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, region_scr_bottom + 1))) break;
195 582 region_scr_bottom++;
196 }
197
198 274 region.region_id = get_region_id(map, origin_scr);
199 274 region.origin_screen = origin_scr;
200 274 region.origin_screen_x = origin_scr_x;
201 274 region.origin_screen_y = origin_scr_y;
202 274 region.screen_width = region_scr_right - origin_scr_x + 1;
203 274 region.screen_height = region_scr_bottom - origin_scr_y + 1;
204 274 region.screen_count = region.screen_width * region.screen_height;
205 274 region.width = 256 * region.screen_width;
206 274 region.height = 176 * region.screen_height;
207 274 region_scr_dx = input_scr_x - origin_scr_x;
208 274 region_scr_dy = input_scr_y - origin_scr_y;
209
210 DCHECK_RANGE_INCLUSIVE(region.screen_width, 0, 16);
211 DCHECK_RANGE_INCLUSIVE(region.screen_height, 0, 8);
212 67250 }
213
214 37536 void load_region(int dmap, int screen)
215 {
216 37536 clear_temporary_screens();
217
218 37536 int map = DMaps[dmap].map;
219 37536 current_region_ids = Regions[map].get_all_region_ids();
220
221 37536 calculate_region(map, screen, cur_region, region_scr_dx, region_scr_dy);
222 37536 cur_screen = cur_region.origin_screen;
223 37536 world_w = cur_region.width;
224 37536 world_h = cur_region.height;
225 37536 region_scr_count = cur_region.screen_count;
226 37536 region_max_rpos = (rpos_t)(cur_region.screen_count*176 - 1);
227 37536 region_num_rpos = cur_region.screen_count*176;
228 37536 scrolling_maze_last_solved_screen = 0;
229
230 37536 memset(screen_in_current_region, false, sizeof(screen_in_current_region));
231
2/2
✓ Branch 0 taken 37770 times.
✓ Branch 1 taken 37536 times.
75306 for (int x = 0; x < cur_region.screen_width; x++)
232 {
233
2/2
✓ Branch 0 taken 38780 times.
✓ Branch 1 taken 37770 times.
76550 for (int y = 0; y < cur_region.screen_height; y++)
234 {
235 38780 int screen = cur_screen + x + y*16;
236
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38780 times.
38780 if (screen < 136)
237 {
238 38780 screen_in_current_region[screen] = true;
239 38780 }
240 38780 }
241 37770 }
242
243 37536 mark_current_region_handles_dirty();
244 37536 }
245
246 37669 static void prepare_current_region_handles()
247 {
248 37669 current_region_rpos_handles_dirty = false;
249 37669 current_region_screen_count = 0;
250
2/2
✓ Branch 0 taken 38023 times.
✓ Branch 1 taken 37669 times.
75692 for (int y = 0; y < cur_region.screen_height; y++)
251 {
252
2/2
✓ Branch 0 taken 38943 times.
✓ Branch 1 taken 38023 times.
76966 for (int x = 0; x < cur_region.screen_width; x++)
253 {
254 38943 int screen = cur_screen + x + y*16;
255 38943 mapscr* base_scr = get_scr(screen);
256
1/2
✓ Branch 0 taken 38943 times.
✗ Branch 1 not taken.
38943 if (!base_scr->is_valid())
257 continue;
258
259 38943 int index_start = current_region_screen_count;
260
261
2/2
✓ Branch 0 taken 272601 times.
✓ Branch 1 taken 38943 times.
311544 for (int layer = 0; layer <= 6; layer++)
262 {
263 272601 mapscr* scr = get_scr_layer(screen, layer);
264
2/2
✓ Branch 0 taken 95882 times.
✓ Branch 1 taken 176719 times.
272601 if (!scr->is_valid())
265 176719 continue;
266
267 95882 rpos_t base_rpos = POS_TO_RPOS(0, get_region_relative_dx(screen), get_region_relative_dy(screen));
268 95882 current_region_rpos_handles[current_region_screen_count] = {base_scr, scr, screen, layer, base_rpos, 0};
269 95882 current_region_screen_count += 1;
270 95882 }
271
272 38943 int num_handles_for_scr = current_region_screen_count - index_start;
273 38943 current_region_rpos_handles_scr[screen] = {&current_region_rpos_handles[index_start], num_handles_for_scr};
274 38943 }
275 38023 }
276 37669 }
277
278 1735230417 std::tuple<const rpos_handle_t*, int> get_current_region_handles()
279 {
280
2/2
✓ Branch 0 taken 1735230284 times.
✓ Branch 1 taken 133 times.
1735230417 if (current_region_rpos_handles_dirty)
281 133 prepare_current_region_handles();
282 1735230417 return {current_region_rpos_handles, current_region_screen_count};
283 }
284
285 11484498 std::tuple<const rpos_handle_t*, int> get_current_region_handles(mapscr* scr)
286 {
287
1/2
✓ Branch 0 taken 11484498 times.
✗ Branch 1 not taken.
11484498 if (current_region_rpos_handles_dirty)
288 prepare_current_region_handles();
289
1/2
✓ Branch 0 taken 11484498 times.
✗ Branch 1 not taken.
11484498 if (scr == special_warp_return_scr)
290 return {nullptr, 0};
291
292
2/2
✓ Branch 0 taken 65877 times.
✓ Branch 1 taken 11418621 times.
11484498 if (cur_screen >= 0x80)
293 {
294 DCHECK(scr == origin_scr);
295 65877 return {nullptr, 0};
296 }
297
298 DCHECK(is_in_current_region(scr));
299 11418621 return current_region_rpos_handles_scr[scr->screen];
300 11484498 }
301
302 37691 void mark_current_region_handles_dirty()
303 {
304 37691 current_region_rpos_handles_dirty = true;
305 37691 }
306
307 68014 void delete_temporary_screens(mapscr** screens)
308 {
309
2/2
✓ Branch 0 taken 64749328 times.
✓ Branch 1 taken 68014 times.
64817342 for (int i = 0; i < 136*7; i++)
310 {
311
2/2
✓ Branch 0 taken 267372 times.
✓ Branch 1 taken 64481956 times.
64749328 if (!screens[i])
312 64481956 continue;
313
314 267372 mapscr* scr = screens[i];
315 267372 int num_ffcs = scr->numFFC();
316
2/2
✓ Branch 0 taken 7621503 times.
✓ Branch 1 taken 267372 times.
7888875 for (int i = 0; i < num_ffcs; i++)
317 {
318 7621503 sprite* ffc = &scr->ffcs[i];
319
2/2
✓ Branch 0 taken 7617968 times.
✓ Branch 1 taken 3535 times.
7621503 if (ffc->uid)
320 3535 FFCore.release_sprite_owned_objects(ffc->uid);
321 7621503 }
322
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 267372 times.
267372 delete scr;
323 267372 screens[i] = NULL;
324 267372 }
325 68014 }
326
327 38711 void clear_temporary_screens()
328 {
329 38711 delete_temporary_screens(temporary_screens);
330 38711 origin_scr = nullptr;
331 38711 hero_scr = nullptr;
332 38711 }
333
334 29307 std::vector<mapscr*> take_temporary_scrs()
335 {
336
1/2
✓ Branch 0 taken 29307 times.
✗ Branch 1 not taken.
29307 std::vector<mapscr*> screens(temporary_screens, temporary_screens + 136*7);
337
2/2
✓ Branch 0 taken 29307 times.
✓ Branch 1 taken 27900264 times.
27929571 for (int i = 0; i < 136*7; i++)
338 27900264 temporary_screens[i] = nullptr;
339
340 29307 return screens;
341
1/2
✓ Branch 0 taken 29307 times.
✗ Branch 1 not taken.
29307 }
342
343 15079645 void calculate_viewport(viewport_t& viewport, int dmap, int screen, int world_w, int world_h, int x, int y)
344 {
345 // TODO: In future, maybe add x/y centering offsets to zscript (Viewport->TargetXOffset/Viewport->TargetYOffset).
346
347
2/2
✓ Branch 0 taken 15033063 times.
✓ Branch 1 taken 46582 times.
15079645 bool extended_height_mode = (DMaps[dmap].flags & dmfEXTENDEDVIEWPORT) && world_h > 176;
348 15079645 viewport.w = 256;
349 15079645 viewport.h = 176 + (extended_height_mode ? 56 : 0);
350
351
2/2
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 15079285 times.
15079645 if (viewport_mode == ViewportMode::Script)
352 360 return;
353
354
2/2
✓ Branch 0 taken 46162 times.
✓ Branch 1 taken 15033123 times.
15079285 if (!is_in_scrolling_region(DMaps[dmap].map, screen))
355 {
356 15033123 viewport.x = 0;
357 15033123 viewport.y = 0;
358 15033123 }
359
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46162 times.
46162 else if (viewport_mode == ViewportMode::CenterAndBound)
360 {
361 // Clamp the viewport to the edges of the region.
362
6/6
✓ Branch 0 taken 8568 times.
✓ Branch 1 taken 37594 times.
✓ Branch 2 taken 6788 times.
✓ Branch 3 taken 39374 times.
✓ Branch 4 taken 8568 times.
✓ Branch 5 taken 30806 times.
46162 viewport.x = CLAMP(0, world_w - viewport.w, x - viewport.w/2);
363
6/6
✓ Branch 0 taken 11856 times.
✓ Branch 1 taken 34306 times.
✓ Branch 2 taken 5650 times.
✓ Branch 3 taken 40512 times.
✓ Branch 4 taken 11856 times.
✓ Branch 5 taken 28656 times.
46162 viewport.y = CLAMP(0, world_h - viewport.h, y - viewport.h/2);
364 46162 }
365 else if (viewport_mode == ViewportMode::Center)
366 {
367 viewport.x = x - viewport.w/2;
368 viewport.y = y - viewport.h/2;
369 }
370 15079645 }
371
372 15079134 sprite* get_viewport_sprite()
373 {
374 15079134 sprite* spr = sprite::getByUID(viewport_sprite_uid);
375
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 15079128 times.
15079134 if (!spr)
376 {
377 6 viewport_sprite_uid = 1; // Hero uid.
378 6 spr = &Hero;
379 6 }
380
381 15079134 return spr;
382 }
383
384 6 void set_viewport_sprite(sprite* spr)
385 {
386 6 viewport_sprite_uid = spr->uid;
387 6 }
388
389 15049827 void update_viewport()
390 {
391 15049827 sprite* spr = get_viewport_sprite();
392 15049827 int x = spr->x + spr->txsz*16/2;
393 15049827 int y = spr->y + spr->tysz*16/2;
394 15049827 calculate_viewport(viewport, cur_dmap, cur_screen, world_w, world_h, x, y);
395 15049827 }
396
397 // TODO: should add a moveflag to sprites to configure the size of this rect (or effectively disable
398 // freezing if the rect returns is large enough). See:
399 // https://discord.com/channels/876899628556091432/1358483603700449581
400 // https://discord.com/channels/876899628556091432/1130384911983980554
401 //
402 89034844 viewport_t get_sprite_freeze_rect()
403 {
404 89034844 viewport_t freeze_rect = viewport;
405 89034844 int tile_buffer = 3;
406 89034844 freeze_rect.w += 16 * tile_buffer * 2;
407 89034844 freeze_rect.h += 16 * tile_buffer * 2;
408 89034844 freeze_rect.x -= 16 * tile_buffer;
409 89034844 freeze_rect.y -= 16 * tile_buffer;
410 89034844 return freeze_rect;
411 }
412
413 4722 mapscr* determine_hero_screen_from_coords()
414 {
415 4722 int x = vbound(Hero.getX().getInt(), 0, world_w - 1);
416 4722 int y = vbound(Hero.getY().getInt(), 0, world_h - 1);
417 4722 int dx = x / 256;
418 4722 int dy = y / 176;
419 4722 return get_scr(cur_screen + dx + dy * 16);
420 }
421
422 28218 bool edge_of_region(direction dir)
423 {
424
2/2
✓ Branch 0 taken 28138 times.
✓ Branch 1 taken 80 times.
28218 if (!is_in_scrolling_region()) return true;
425
426 80 int screen_x = Hero.current_screen % 16;
427 80 int screen_y = Hero.current_screen / 16;
428
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 2 times.
80 if (dir == up) screen_y -= 1;
429
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 10 times.
80 if (dir == down) screen_y += 1;
430
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 30 times.
80 if (dir == left) screen_x -= 1;
431
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 38 times.
80 if (dir == right) screen_x += 1;
432
4/8
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 80 times.
✗ Branch 7 not taken.
80 if (screen_x < 0 || screen_x > 16 || screen_y < 0 || screen_y > 8) return true;
433 80 return !is_in_current_region(map_scr_xy_to_index(screen_x, screen_y));
434 28218 }
435
436 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
437 // Coordinates are clamped to the world bounds.
438 338039260 int get_screen_for_world_xy(int x, int y)
439 {
440
2/2
✓ Branch 0 taken 316968806 times.
✓ Branch 1 taken 21070454 times.
338039260 if (!is_in_scrolling_region())
441 316968806 return cur_screen;
442
443 21070454 int dx = std::clamp(x, 0, world_w - 1) / 256;
444 21070454 int dy = std::clamp(y, 0, world_h - 1) / 176;
445 21070454 int origin_screen_x = cur_screen % 16;
446 21070454 int origin_screen_y = cur_screen / 16;
447 21070454 int scr_x = origin_screen_x + dx;
448 21070454 int scr_y = origin_screen_y + dy;
449 21070454 return map_scr_xy_to_index(scr_x, scr_y);
450 338039260 }
451
452 31102119 int get_screen_for_rpos(rpos_t rpos)
453 {
454 31102119 int origin_screen_x = cur_screen % 16;
455 31102119 int origin_screen_y = cur_screen / 16;
456 31102119 int screen = static_cast<int32_t>(rpos) / 176;
457 31102119 int scr_x = origin_screen_x + screen%cur_region.screen_width;
458 31102119 int scr_y = origin_screen_y + screen/cur_region.screen_width;
459 31102119 return map_scr_xy_to_index(scr_x, scr_y);
460 }
461
462 837279632 rpos_handle_t get_rpos_handle(rpos_t rpos, int layer)
463 {
464 DCHECK_LAYER_ZERO_INDEX(layer);
465
2/2
✓ Branch 0 taken 806315476 times.
✓ Branch 1 taken 30964156 times.
837279632 if (!is_in_scrolling_region())
466 806315476 return {origin_scr, get_scr_layer(cur_screen, layer), cur_screen, layer, rpos, RPOS_TO_POS(rpos)};
467
468 30964156 int screen = get_screen_for_rpos(rpos);
469 30964156 mapscr* scr = get_scr_layer(screen, layer);
470
2/2
✓ Branch 0 taken 1702286 times.
✓ Branch 1 taken 29261870 times.
30964156 mapscr* base_scr = layer == 0 ? scr : get_scr(screen);
471 30964156 return {base_scr, scr, screen, layer, rpos, RPOS_TO_POS(rpos)};
472 837279632 }
473
474 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
475 // Coordinates are clamped to the world bounds.
476 3485889486 rpos_handle_t get_rpos_handle_for_world_xy(int x, int y, int layer)
477 {
478 3485889486 x = std::clamp(x, 0, world_w - 1);
479 3485889486 y = std::clamp(y, 0, world_h - 1);
480
481 DCHECK_LAYER_ZERO_INDEX(layer);
482
2/2
✓ Branch 0 taken 3459546960 times.
✓ Branch 1 taken 26342526 times.
3485889486 if (!is_in_scrolling_region())
483 {
484 3459546960 int pos = COMBOPOS(x, y);
485 3459546960 mapscr* scr = get_scr_layer(cur_screen, layer);
486 3459546960 return {origin_scr, scr, cur_screen, layer, (rpos_t)pos, pos};
487 }
488
489 26342526 return get_rpos_handle(COMBOPOS_REGION(x, y), layer);
490 3485889486 }
491
492 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
493 1926 rpos_handle_t get_rpos_handle_for_screen(int screen, int layer, int pos)
494 {
495 DCHECK_LAYER_ZERO_INDEX(layer);
496 1926 mapscr* scr = get_scr_layer(screen, layer);
497
2/2
✓ Branch 0 taken 1904 times.
✓ Branch 1 taken 22 times.
1926 mapscr* base_scr = layer == 0 ? scr : get_scr(screen);
498 1926 return {base_scr, scr, screen, layer, POS_TO_RPOS(pos, screen), pos};
499 }
500
501 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
502 // Use this instead of the other `get_pos_handle_for_screen` if you already have a reference to the screen.
503 // `scr` must be from the active region.
504 63140 rpos_handle_t get_rpos_handle_for_scr(mapscr* scr, int layer, int pos)
505 {
506 DCHECK_LAYER_ZERO_INDEX(layer);
507
1/2
✓ Branch 0 taken 63140 times.
✗ Branch 1 not taken.
63140 mapscr* base_scr = layer == 0 ? scr : get_scr(scr->map, scr->screen);
508 63140 return {base_scr, scr, scr->screen, layer, POS_TO_RPOS(pos, scr->screen), pos};
509 }
510
511 25594159 void change_rpos_handle_layer(rpos_handle_t& rpos_handle, int layer)
512 {
513 DCHECK_LAYER_ZERO_INDEX(layer);
514 25594159 rpos_handle.layer = layer;
515 25594159 rpos_handle.scr = get_scr_layer(rpos_handle.screen, layer);
516 25594159 }
517
518 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
519 // Coordinates are clamped to the world bounds.
520 86712 combined_handle_t get_combined_handle_for_world_xy(int x, int y, int layer)
521 {
522 DCHECK_LAYER_ZERO_INDEX(layer);
523
524 86712 x = std::clamp(x, 0, world_w - 1);
525 86712 y = std::clamp(y, 0, world_h - 1);
526
527 86712 auto maybe_ffc_handle = getFFCAt(x, y);
528
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 86712 times.
86712 if (maybe_ffc_handle)
529 return maybe_ffc_handle.value();
530
531 86712 auto rpos = COMBOPOS_REGION_B(x, y);
532
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 86712 times.
86712 if (rpos == rpos_t::None)
533 return rpos_handle_t();
534 86712 return get_rpos_handle(rpos, layer);
535 86712 }
536
537 // These functions all return _temporary_ screens. Any modifications made to them (either by the engine
538 // directly or via zscript) only last until the next area is loaded (via loadscr).
539
540 // Returns the screen containing the (x, y) world position.
541 1542441114 mapscr* get_scr_for_world_xy(int x, int y)
542 {
543 // Quick path, but should work the same without.
544
2/2
✓ Branch 0 taken 1532070300 times.
✓ Branch 1 taken 10370814 times.
1542441114 if (!is_in_scrolling_region()) return origin_scr;
545 10370814 return get_scr(get_screen_for_world_xy(x, y));
546 1542441114 }
547
548 26000958 mapscr* get_scr_for_rpos(rpos_t rpos)
549 {
550 // Quick path, but should work the same without.
551
2/2
✓ Branch 0 taken 25863012 times.
✓ Branch 1 taken 137946 times.
26000958 if (!is_in_scrolling_region()) return origin_scr;
552 137946 return get_scr(get_screen_for_rpos(rpos));
553 26000958 }
554
555 17 mapscr* get_scr_for_rpos_layer(rpos_t rpos, int layer)
556 {
557 17 return get_scr_layer(get_screen_for_rpos(rpos), layer);
558 }
559
560 // Note: layer=0 is the base screen, 1 is the first layer, etc.
561 2135678557 mapscr* get_scr_for_world_xy_layer(int x, int y, int layer)
562 {
563 DCHECK_LAYER_ZERO_INDEX(layer);
564
2/2
✓ Branch 0 taken 2125633327 times.
✓ Branch 1 taken 10045230 times.
2135678557 if (!is_in_scrolling_region()) return get_scr_layer(cur_screen, layer);
565
2/2
✓ Branch 0 taken 708934 times.
✓ Branch 1 taken 9336296 times.
10045230 return layer == 0 ?
566 708934 get_scr_for_world_xy(x, y) :
567 9336296 get_scr_layer(get_screen_for_world_xy(x, y), layer);
568 2135678557 }
569
570 1748714793 int get_region_screen_offset(int screen)
571 {
572 1748714793 return get_region_relative_dx(screen) + get_region_relative_dy(screen) * cur_region.screen_width;
573 }
574
575 655240230 int get_screen_for_region_index_offset(int offset)
576 {
577 655240230 int scr_dx = offset % cur_region.screen_width;
578 655240230 int scr_dy = offset / cur_region.screen_width;
579 655240230 int screen = cur_screen + scr_dx + scr_dy*16;
580 655240230 return screen;
581 }
582
583 655056392 mapscr* get_scr_for_region_index_offset(int offset)
584 {
585 655056392 int screen = get_screen_for_region_index_offset(offset);
586 655056392 return get_scr(screen);
587 }
588
589 // The screen at (map, screen) must exist.
590 1663274699 mapscr* get_scr(int map, int screen)
591 {
592 1663274699 mapscr* scr = get_scr_maybe(map, screen);
593
1/2
✓ Branch 0 taken 1663274699 times.
✗ Branch 1 not taken.
1663274699 CHECK(scr);
594 1663274699 return scr;
595 }
596
597 870710307 mapscr* get_scr(int screen)
598 {
599 870710307 return get_scr(cur_map, screen);
600 }
601
602 // Returns null if active screen does not exist.
603 1849124306 mapscr* get_scr_maybe(int map, int screen)
604 {
605 DCHECK_RANGE_INCLUSIVE(screen, 0, 135);
606
607
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1849124306 times.
1849124306 if (map == cur_map)
608 {
609
2/2
✓ Branch 0 taken 1803231252 times.
✓ Branch 1 taken 45893054 times.
1849124306 if (screen == cur_screen)
610 1803231252 return origin_scr;
611
612 45893054 int index = screen*7;
613
2/2
✓ Branch 0 taken 45869352 times.
✓ Branch 1 taken 23702 times.
45893054 if (temporary_screens[index])
614 45869352 return temporary_screens[index];
615
616
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23702 times.
23702 if (screen == home_screen)
617 return special_warp_return_scr;
618 23702 }
619
620
4/6
✓ Branch 0 taken 23700 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 23700 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 23700 times.
23702 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
621 {
622 23700 int index = screen*7;
623
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23700 times.
23700 if (FFCore.ScrollingScreensAll[index])
624 23700 return FFCore.ScrollingScreensAll[index];
625 }
626
627 2 return nullptr;
628 1849124306 }
629
630 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
631 7083620353 mapscr* get_scr_layer(int map, int screen, int layer)
632 {
633 DCHECK_LAYER_ZERO_INDEX(layer);
634
2/2
✓ Branch 0 taken 6291116058 times.
✓ Branch 1 taken 792504295 times.
7083620353 if (layer == 0)
635 792504295 return get_scr(map, screen);
636
637
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6291116058 times.
6291116058 if (map == cur_map)
638 {
639 6291116058 int index = screen*7 + layer;
640
2/2
✓ Branch 0 taken 6290971998 times.
✓ Branch 1 taken 144060 times.
6291116058 if (temporary_screens[index])
641 6290971998 return temporary_screens[index];
642
643
2/2
✓ Branch 0 taken 1860 times.
✓ Branch 1 taken 142200 times.
144060 if (screen == home_screen)
644 1860 return &special_warp_return_scrs[layer];
645 142200 }
646
647
1/2
✓ Branch 0 taken 142200 times.
✗ Branch 1 not taken.
142200 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
648 {
649 142200 int index = screen*7 + layer;
650
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 142200 times.
142200 if (FFCore.ScrollingScreensAll[index])
651 142200 return FFCore.ScrollingScreensAll[index];
652 }
653
654 NOTREACHED();
655 7083620353 }
656
657 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
658 6661473421 mapscr* get_scr_layer(int screen, int layer)
659 {
660 6661473421 return get_scr_layer(cur_map, screen, layer);
661 }
662
663 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
664 // Return nullptr if screen is not valid.
665 419166575 mapscr* get_scr_layer_valid(int screen, int layer)
666 {
667
2/2
✓ Branch 0 taken 98849151 times.
✓ Branch 1 taken 320317424 times.
419166575 if (mapscr* scr = get_scr_layer(cur_map, screen, layer); scr->is_valid())
668 98849151 return scr;
669 320317424 return nullptr;
670 419166575 }
671
672 401 mapscr* get_scr_current_region_dir(int screen, direction dir)
673 {
674 401 int x = get_region_relative_dx(screen);
675 401 int y = get_region_relative_dy(screen);
676
3/4
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 330 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 71 times.
401 if (dir == left && x == 0)
677 71 return nullptr;
678
3/4
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 238 times.
✓ Branch 2 taken 92 times.
✗ Branch 3 not taken.
330 if (dir == right && x == 15)
679 return nullptr;
680
3/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 281 times.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
330 if (dir == down && y == 7)
681 return nullptr;
682
3/4
✓ Branch 0 taken 189 times.
✓ Branch 1 taken 141 times.
✓ Branch 2 taken 189 times.
✗ Branch 3 not taken.
330 if (dir == up && y == 0)
683 189 return nullptr;
684
685 141 screen = screen_index_direction(screen, dir);
686
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 if (is_in_current_region(screen))
687 return get_scr(screen);
688
689 141 return nullptr;
690 401 }
691
692 183838 ffc_handle_t get_ffc_handle(ffc_id_t id)
693 {
694 183838 uint8_t screen = get_screen_for_region_index_offset(id / MAXFFCS);
695 183838 uint8_t i = id % MAXFFCS;
696 183838 mapscr* scr = get_scr(screen);
697 183838 ffcdata* ffc = &scr->getFFC(id % MAXFFCS);
698 183838 return {scr, screen, id, i, ffc};
699 }
700
701 34571 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen, int x, int y)
702 {
703 34571 x += get_region_relative_dx(screen) * 256;
704 34571 y += get_region_relative_dy(screen) * 176;
705 34571 return {x, y};
706 }
707
708 1056055 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen)
709 {
710 1056055 int x = get_region_relative_dx(screen) * 256;
711 1056055 int y = get_region_relative_dy(screen) * 176;
712 1056055 return {x, y};
713 }
714
715 12678650115 int32_t COMBOPOS(int32_t x, int32_t y)
716 {
717 DCHECK(x >= 0 && x < 256 && y >= 0 && y < 176);
718 12678650115 return (y & 0xF0) + (x >> 4);
719 }
720 int32_t COMBOPOS_B(int32_t x, int32_t y)
721 {
722 if(unsigned(x) >= 256 || unsigned(y) >= 176)
723 return -1;
724 return (y & 0xF0) + (x >> 4);
725 }
726 3952345454 int32_t COMBOX(int32_t pos)
727 {
728 3952345454 return pos % 16 * 16;
729 }
730 3952345454 int32_t COMBOY(int32_t pos)
731 {
732 3952345454 return pos & 0xF0;
733 }
734
735 116980740 rpos_t COMBOPOS_REGION(int32_t x, int32_t y)
736 {
737
2/2
✓ Branch 0 taken 89822740 times.
✓ Branch 1 taken 27158000 times.
116980740 if (!is_in_scrolling_region())
738 89822740 return (rpos_t) COMBOPOS(x, y);
739
740 DCHECK(is_in_world_bounds(x, y));
741 27158000 int scr_dx = x / (16*16);
742 27158000 int scr_dy = y / (11*16);
743 27158000 int pos = COMBOPOS(x%256, y%176);
744 27158000 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
745 116980740 }
746 6959671028 rpos_t COMBOPOS_REGION_B(int32_t x, int32_t y)
747 {
748
2/2
✓ Branch 0 taken 1546535 times.
✓ Branch 1 taken 6958124493 times.
6959671028 if (!is_in_world_bounds(x, y))
749 1546535 return rpos_t::None;
750
751 6958124493 int scr_dx = x / (16*16);
752 6958124493 int scr_dy = y / (11*16);
753 6958124493 int pos = COMBOPOS(x%256, y%176);
754 6958124493 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
755 6959671028 }
756 27490422 std::pair<int32_t, int32_t> COMBOXY_REGION(rpos_t rpos)
757 {
758 27490422 int scr_index = static_cast<int32_t>(rpos) / 176;
759 27490422 int scr_dx = scr_index % cur_region.screen_width;
760 27490422 int scr_dy = scr_index / cur_region.screen_width;
761 27490422 int pos = RPOS_TO_POS(rpos);
762 27490422 int x = scr_dx*16*16 + COMBOX(pos);
763 27490422 int y = scr_dy*11*16 + COMBOY(pos);
764 27490422 return {x, y};
765 }
766 182363 int32_t COMBOX_REGION(rpos_t rpos)
767 {
768 182363 auto [x, y] = COMBOXY_REGION(rpos);
769 182363 return x;
770 }
771 134192 int32_t COMBOY_REGION(rpos_t rpos)
772 {
773 134192 auto [x, y] = COMBOXY_REGION(rpos);
774 134192 return y;
775 }
776
777 70177 rpos_t COMBOPOS_REGION_INDEX(int32_t x, int32_t y)
778 {
779 DCHECK(is_in_world_bounds(x, y));
780
1/2
✓ Branch 0 taken 70177 times.
✗ Branch 1 not taken.
70177 if (!is_in_scrolling_region())
781 70177 return (rpos_t)(x + y * 16);
782
783 int scr_dx = x / 16;
784 int scr_dy = y / 11;
785 x %= 16;
786 y %= 11;
787 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + x + y * 16);
788 70177 }
789 70632 std::pair<int32_t, int32_t> COMBOXY_REGION_INDEX(rpos_t rpos)
790 {
791 70632 int scr_index = static_cast<int32_t>(rpos) / 176;
792 70632 int scr_dx = scr_index % cur_region.screen_width;
793 70632 int scr_dy = scr_index / cur_region.screen_width;
794 70632 int pos = RPOS_TO_POS(rpos);
795 70632 int x = scr_dx*16 + pos%16;
796 70632 int y = scr_dy*11 + pos/16;
797 70632 return {x, y};
798 }
799
800 92319834 int32_t mapind(int32_t map, int32_t screen)
801 {
802 92319834 return map * MAPSCRSNORMAL + screen;
803 }
804
805 FONT *get_zc_font(int index);
806
807 extern sprite_list guys, items, Ewpns, Lwpns, chainlinks, decorations;
808 extern movingblock mblock2; //mblock[4]?
809 extern portal mirror_portal;
810
811 void Z_message_d(const char *format,...)
812 {
813 #ifdef _DEBUG
814 char buf[512];
815 va_list ap;
816 va_start(ap, format);
817 vsprintf(buf, format, ap);
818 va_end(ap);
819
820 al_trace("%s",buf);
821 #else
822 format=format;
823 #endif
824 }
825
826
827
828 bool checktrigger=false;
829
830 void clear_dmap(word i)
831 {
832 DMaps[i].clear();
833 }
834
835 void clear_dmaps()
836 {
837 for(int32_t i=0; i<MAXDMAPS; i++)
838 {
839 clear_dmap(i);
840 }
841 }
842
843 235198941 int32_t isdungeon(int32_t dmap, int32_t screen)
844 {
845
2/2
✓ Branch 0 taken 235151581 times.
✓ Branch 1 taken 47360 times.
235198941 if (dmap < 0) dmap = cur_dmap;
846
847 // dungeons can have any dlevel above 0
848
2/2
✓ Branch 0 taken 133949496 times.
✓ Branch 1 taken 101249445 times.
235198941 if((DMaps[dmap].type&dmfTYPE) == dmDNGN)
849 {
850
2/2
✓ Branch 0 taken 9961 times.
✓ Branch 1 taken 101239484 times.
101249445 if (get_canonical_scr(cur_map, screen)->flags6&fCAVEROOM)
851 9961 return 0;
852
853 101239484 return 1;
854 }
855
856 // dlevels that aren't dungeons are caves
857
2/2
✓ Branch 0 taken 36827 times.
✓ Branch 1 taken 133912669 times.
133949496 if (get_canonical_scr(cur_map, screen)->flags6&fDUNGEONROOM)
858 36827 return 1;
859
860 133912669 return 0;
861 235198941 }
862
863 43127602 int32_t isdungeon(int32_t screen)
864 {
865 43127602 return isdungeon(cur_dmap, screen);
866 }
867
868 191939187 int32_t isdungeon()
869 {
870 191939187 return isdungeon(cur_dmap, Hero.current_screen);
871 }
872
873 92465 bool canPermSecret(int32_t dmap, int32_t screen)
874 {
875
2/2
✓ Branch 0 taken 13910 times.
✓ Branch 1 taken 78555 times.
92465 return (!isdungeon(dmap, screen) || get_qr(qr_DUNGEON_DMAPS_PERM_SECRETS));
876 }
877
878 1261656255 int32_t MAPCOMBO(int32_t x, int32_t y)
879 {
880
2/2
✓ Branch 0 taken 10632143 times.
✓ Branch 1 taken 1251024112 times.
1261656255 if (!is_in_world_bounds(x, y))
881 10632143 return 0;
882 1251024112 int pos = COMBOPOS(x%256, y%176);
883 1251024112 mapscr* scr = get_scr_for_world_xy(x, y);
884 1251024112 return scr->data[pos];
885 1261656255 }
886
887 //specific layers 1 to 6
888 1488665081 int32_t MAPCOMBOL(int32_t layer,int32_t x,int32_t y)
889 {
890 DCHECK(layer >= 1 && layer <= 6);
891
3/4
✓ Branch 0 taken 1468815731 times.
✓ Branch 1 taken 19849350 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1468815731 times.
1488665081 if (!is_in_world_bounds(x, y) || layer <= 0)
892 19849350 return 0;
893
894 1468815731 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
895
2/2
✓ Branch 0 taken 472758528 times.
✓ Branch 1 taken 996057203 times.
1468815731 if (!m->is_valid())
896 996057203 return 0;
897
898 472758528 int pos = COMBOPOS(x%256, y%176);
899 472758528 return m->data[pos];
900 1488665081 }
901
902 int32_t MAPCSETL(int32_t layer,int32_t x,int32_t y)
903 {
904 DCHECK(layer >= 1 && layer <= 6);
905 if (!is_in_world_bounds(x, y) || layer <= 0)
906 return 0;
907
908 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
909 if (!m->is_valid())
910 return 0;
911
912 int pos = COMBOPOS(x%256, y%176);
913 return m->cset[pos];
914 }
915
916 372352 int32_t MAPFLAGL(int32_t layer,int32_t x,int32_t y)
917 {
918 DCHECK(layer >= 1 && layer <= 6);
919
2/4
✓ Branch 0 taken 372352 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 372352 times.
372352 if (!is_in_world_bounds(x, y) || layer <= 0)
920 return 0;
921
922 372352 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
923
2/2
✓ Branch 0 taken 345286 times.
✓ Branch 1 taken 27066 times.
372352 if (!m->is_valid())
924 27066 return 0;
925
926 345286 int pos = COMBOPOS(x%256, y%176);
927 345286 return m->sflag[pos];
928 372352 }
929
930 40979 int32_t COMBOTYPEL(int32_t layer,int32_t x,int32_t y)
931 {
932 DCHECK(layer >= 1 && layer <= 6);
933
2/4
✓ Branch 0 taken 40979 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40979 times.
40979 if (!is_in_world_bounds(x, y) || layer <= 0)
934 return 0;
935
936 40979 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
937
2/2
✓ Branch 0 taken 40624 times.
✓ Branch 1 taken 355 times.
40979 if (!m->is_valid())
938 355 return 0;
939
940 40624 int pos = COMBOPOS(x%256, y%176);
941 40624 return combobuf[m->data[pos]].type;
942 40979 }
943
944 371064 int32_t MAPCOMBOFLAGL(int32_t layer,int32_t x,int32_t y)
945 {
946 DCHECK(layer >= 1 && layer <= 6);
947
2/4
✓ Branch 0 taken 371064 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 371064 times.
371064 if (!is_in_world_bounds(x, y) || layer <= 0)
948 return 0;
949
950 371064 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
951
2/2
✓ Branch 0 taken 343998 times.
✓ Branch 1 taken 27066 times.
371064 if (!m->is_valid())
952 27066 return 0;
953
954 343998 int pos = COMBOPOS(x%256, y%176);
955 343998 return combobuf[m->data[pos]].flag;
956 371064 }
957
958 // True if the FFC covers x, y and is not ethereal or a changer.
959 2536390157 bool ffcIsAt(const ffc_handle_t& ffc_handle, int32_t x, int32_t y)
960 {
961
2/2
✓ Branch 0 taken 750008244 times.
✓ Branch 1 taken 1786381913 times.
2536390157 if (ffc_handle.data() <= 0)
962 750008244 return false;
963
964
2/2
✓ Branch 0 taken 285071655 times.
✓ Branch 1 taken 1501310258 times.
1786381913 if((ffc_handle.ffc->flags&(ffc_changer|ffc_ethereal))!=0)
965 285071655 return false;
966
967 1501310258 int32_t fx = ffc_handle.ffc->x.getInt();
968 1501310258 int32_t w = ffc_handle.scr->ffEffectWidth(ffc_handle.i) - 1;
969
2/2
✓ Branch 0 taken 1390954888 times.
✓ Branch 1 taken 110355370 times.
1501310258 if (static_cast<uint32_t>(x - fx) > static_cast<uint32_t>(w))
970 1390954888 return false;
971
972 110355370 int32_t fy = ffc_handle.ffc->y.getInt();
973 110355370 int32_t h = ffc_handle.scr->ffEffectHeight(ffc_handle.i) - 1;
974
2/2
✓ Branch 0 taken 90405465 times.
✓ Branch 1 taken 19949905 times.
110355370 if (static_cast<uint32_t>(y - fy) > static_cast<uint32_t>(h))
975 90405465 return false;
976
977 19949905 return true;
978 2536390157 }
979
980 829864563 int32_t MAPFFCOMBO(int32_t x,int32_t y)
981 {
982
2/2
✓ Branch 0 taken 11864558 times.
✓ Branch 1 taken 818000005 times.
829864563 if (auto ffc_handle = getFFCAt(x, y))
983 11864558 return ffc_handle->data();
984 818000005 return 0;
985 829864563 }
986
987 207232 int32_t MAPCSET(int32_t x, int32_t y)
988 {
989
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 207232 times.
207232 if (!is_in_world_bounds(x, y))
990 return 0;
991 207232 mapscr* scr = get_scr_for_world_xy(x, y);
992 207232 int pos = COMBOPOS(x%256, y%176);
993 207232 return scr->cset[pos];
994 207232 }
995
996 87073734 int32_t MAPFLAG(int32_t x, int32_t y)
997 {
998
2/2
✓ Branch 0 taken 1435 times.
✓ Branch 1 taken 87072299 times.
87073734 if (!is_in_world_bounds(x, y))
999 1435 return 0;
1000 87072299 mapscr* scr = get_scr_for_world_xy(x, y);
1001 87072299 int pos = COMBOPOS(x%256, y%176);
1002 87072299 return scr->sflag[pos];
1003 87073734 }
1004
1005 95565241 int32_t COMBOTYPE(int32_t x,int32_t y)
1006 {
1007 95565241 int32_t b=1;
1008
2/2
✓ Branch 0 taken 64714849 times.
✓ Branch 1 taken 30850392 times.
95565241 if(x&8) b<<=2;
1009
2/2
✓ Branch 0 taken 60258908 times.
✓ Branch 1 taken 35306333 times.
95565241 if(y&8) b<<=1;
1010
1011
2/2
✓ Branch 0 taken 191122735 times.
✓ Branch 1 taken 95550004 times.
286672739 for (int32_t i = 0; i <= 1; ++i)
1012 {
1013
2/2
✓ Branch 0 taken 158805424 times.
✓ Branch 1 taken 32317311 times.
191122735 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1014 {
1015
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 158805424 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
158805424 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x, y, i)) return cNONE;
1016 158805424 }
1017 else
1018 {
1019
4/4
✓ Branch 0 taken 18389 times.
✓ Branch 1 taken 32298922 times.
✓ Branch 2 taken 3152 times.
✓ Branch 3 taken 15237 times.
32317311 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x, y, i)) return cNONE;
1020 }
1021 191107498 }
1022
1023 95550004 newcombo const& cmb = combobuf[MAPCOMBO(x,y)];
1024
5/6
✓ Branch 0 taken 3536811 times.
✓ Branch 1 taken 92013193 times.
✓ Branch 2 taken 1909933 times.
✓ Branch 3 taken 1626878 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1909933 times.
95550004 if (cmb.type == cWATER && (cmb.walk&b) && ((cmb.walk>>4)&b))
1025 {
1026
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1909933 times.
1909933 if(cmb.usrflags&cflag4) return cSHALLOWWATER;
1027
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1909933 times.
1909933 if(cmb.usrflags&cflag3) return cNONE;
1028 1909933 }
1029 95550004 return cmb.type;
1030 95565241 }
1031
1032 59029550 int32_t FFCOMBOTYPE(int32_t x,int32_t y)
1033 {
1034 59029550 return combobuf[MAPFFCOMBO(x,y)].type;
1035 }
1036
1037 7010470 int32_t FFORCOMBO(int32_t x, int32_t y)
1038 {
1039
2/2
✓ Branch 0 taken 78389 times.
✓ Branch 1 taken 6932081 times.
7010470 if (auto ffc_handle = getFFCAt(x, y))
1040 78389 return ffc_handle->data();
1041
1042 6932081 return MAPCOMBO(x,y);
1043 7010470 }
1044
1045 int32_t FFORCOMBOTYPE(int32_t x, int32_t y)
1046 {
1047 for (int32_t i = 0; i <= 1; ++i)
1048 {
1049 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1050 {
1051 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1052 }
1053 else
1054 {
1055 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1056 }
1057 }
1058 int32_t b=1;
1059
1060 if(x&8) b<<=2;
1061
1062 if(y&8) b<<=1;
1063 newcombo const& cmb = combobuf[FFORCOMBO(x,y)];
1064 if (cmb.type == cWATER && (cmb.usrflags&cflag4) && (cmb.walk&b)) return cSHALLOWWATER;
1065 if (cmb.type == cWATER && (cmb.usrflags&cflag3) && (cmb.walk&b)) return cNONE;
1066 return cmb.type;
1067 }
1068
1069 int32_t FFORCOMBO_L(int32_t layer, int32_t x, int32_t y)
1070 {
1071 if (auto ffc_handle = getFFCAt(x, y))
1072 return ffc_handle->data();
1073
1074 return layer ? MAPCOMBOL(layer, x, y) : MAPCOMBO(x,y);
1075 }
1076
1077 int32_t FFORCOMBOTYPE_L(int32_t layer, int32_t x, int32_t y)
1078 {
1079 return combobuf[FFORCOMBO_L(layer,x,y)].type;
1080 }
1081
1082 83426528 int32_t MAPCOMBOFLAG(int32_t x,int32_t y)
1083 {
1084
2/2
✓ Branch 0 taken 1147 times.
✓ Branch 1 taken 83425381 times.
83426528 if (!is_in_world_bounds(x, y))
1085 1147 return 0;
1086
1087 83425381 mapscr* scr = get_scr_for_world_xy(x, y);
1088 83425381 int pos = COMBOPOS(x%256, y%176);
1089 83425381 return combobuf[scr->data[pos]].flag;
1090 83426528 }
1091
1092 68112056 int32_t MAPFFCOMBOFLAG(int32_t x,int32_t y)
1093 {
1094
2/2
✓ Branch 0 taken 777663 times.
✓ Branch 1 taken 67334393 times.
68112056 if (auto ffc_handle = getFFCAt(x, y))
1095 777663 return ffc_handle->cflag();
1096
1097 67334393 return 0;
1098 68112056 }
1099
1100 1237804763 std::optional<ffc_handle_t> getFFCAt(int32_t x, int32_t y)
1101 {
1102 2784772455 return find_ffc([&](const ffc_handle_t& ffc_handle) {
1103 1546967692 return ffcIsAt(ffc_handle, x, y);
1104 });
1105 }
1106
1107 3051 int32_t MAPCOMBO(const rpos_handle_t& rpos_handle)
1108 {
1109
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3051 times.
3051 if (!rpos_handle.scr->is_valid()) return 0;
1110 3051 return rpos_handle.data();
1111 3051 }
1112
1113 3016054915 int32_t MAPCOMBO2(int32_t layer, int32_t x, int32_t y)
1114 {
1115 DCHECK_LAYER_NEG1_INDEX(layer);
1116
2/2
✓ Branch 0 taken 21884619 times.
✓ Branch 1 taken 2994170296 times.
3016054915 if (!is_in_world_bounds(x, y)) return 0;
1117
2/2
✓ Branch 0 taken 2897178675 times.
✓ Branch 1 taken 96991621 times.
2994170296 if (layer == -1) return MAPCOMBO(x, y);
1118
1119 2897178675 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1120
2/2
✓ Branch 0 taken 1796663450 times.
✓ Branch 1 taken 1100515225 times.
2897178675 if (!rpos_handle.scr->is_valid()) return 0;
1121
1122 1100515225 return rpos_handle.data();
1123 3016054915 }
1124
1125 19163350 static void _handle_screen_load_trigger(const combined_handle_t& handle)
1126 {
1127 19163350 auto cid = handle.data();
1128 19163350 auto* cmb = &handle.combo();
1129 19163350 bool done = false;
1130 19163350 std::set<int32_t> visited;
1131
2/2
✓ Branch 0 taken 19163350 times.
✓ Branch 1 taken 19163350 times.
38326700 while(!done)
1132 {
1133
2/4
✓ Branch 0 taken 19163350 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19163350 times.
19163350 if(visited.contains(cid))
1134 {
1135 Z_error("Combo '%d' was part of an infinite trigger loop, breaking out of loop", cid);
1136 break; // prevent infinite loop
1137 }
1138
1/2
✓ Branch 0 taken 19163350 times.
✗ Branch 1 not taken.
19163350 visited.insert(cid);
1139
1140 19163350 done = true; // don't loop again unless something changes
1141
1/2
✓ Branch 0 taken 19163350 times.
✗ Branch 1 not taken.
20048915 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
1142 885565 return trig.trigger_flags.get(TRIGFLAG_SCREENLOAD);
1143 });
1144
2/4
✓ Branch 0 taken 19163350 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19163350 times.
19163350 if(handle.data() != cid)
1145 {
1146 cid = handle.data();
1147 cmb = &handle.combo();
1148 done = false; // loop again for the new combo
1149 }
1150 }
1151 19163350 }
1152 52912 static void handle_screen_load_trigger(const screen_handles_t& screen_handles)
1153 {
1154 52912 for_every_combo_in_screen(screen_handles, _handle_screen_load_trigger);
1155 52912 }
1156 36502 void handle_region_load_trigger()
1157 {
1158
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 36350 times.
36502 if (is_in_scrolling_region())
1159 {
1160
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 19456 times.
19608 for (int screen = 0; screen < 128; screen++)
1161 {
1162
2/2
✓ Branch 0 taken 18156 times.
✓ Branch 1 taken 1300 times.
19456 if (is_in_current_region(screen))
1163 1300 handle_screen_load_trigger(create_screen_handles_one(get_scr(screen)));
1164 19456 }
1165 152 }
1166 36350 else handle_screen_load_trigger(create_screen_handles_one(get_scr(Hero.current_screen)));
1167 36502 }
1168
1169 15262 static void apply_state_changes_to_screen(mapscr& scr, int32_t map, int32_t screen, int32_t flags, bool secrets_do_replay_comment)
1170 {
1171 15262 auto screen_handles = create_screen_handles_one(&scr);
1172
1173
3/4
✓ Branch 0 taken 539 times.
✓ Branch 1 taken 14723 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 539 times.
15262 if ((flags & mSECRET) && canPermSecret(cur_dmap, screen))
1174 {
1175 539 reveal_hidden_stairs(&scr, screen, false);
1176 539 bool do_layers = false;
1177 539 bool from_active_screen = false;
1178 539 trigger_secrets_for_screen_internal(screen_handles, do_layers, from_active_screen, -3, secrets_do_replay_comment);
1179 539 }
1180
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if (flags & mLIGHTBEAM)
1181 {
1182 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
1183 if (rpos_handle.ctype() == cLIGHTTARGET)
1184 {
1185 if (!(rpos_handle.combo().usrflags&cflag1)) //Unlit version
1186 rpos_handle.increment_data();
1187 }
1188 });
1189 }
1190
1191 15262 int lvl = DMaps[cur_dmap].level;
1192 15262 toggle_switches(game->lvlswitches[lvl], true, screen_handles);
1193 15262 toggle_gswitches_load(screen_handles);
1194
1195
2/2
✓ Branch 0 taken 15170 times.
✓ Branch 1 taken 92 times.
15262 if(flags&mLOCKBLOCK) // if special stuff done before
1196 {
1197 92 remove_screenstatecombos2(screen_handles, false, cLOCKBLOCK, cLOCKBLOCK2);
1198 92 }
1199
1200
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mBOSSLOCKBLOCK) // if special stuff done before
1201 {
1202 remove_screenstatecombos2(screen_handles, false, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
1203 }
1204
1205
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mCHEST) // if special stuff done before
1206 {
1207 remove_screenstatecombos2(screen_handles, false, cCHEST, cCHEST2);
1208 }
1209
1210
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mCHEST) // if special stuff done before
1211 {
1212 remove_screenstatecombos2(screen_handles, false, cLOCKEDCHEST, cLOCKEDCHEST2);
1213 }
1214
1215
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mBOSSCHEST) // if special stuff done before
1216 {
1217 remove_screenstatecombos2(screen_handles, false, cBOSSCHEST, cBOSSCHEST2);
1218 }
1219
1220
1221 15262 int mi = mapind(map, screen);
1222 15262 clear_xdoors_mi(screen_handles, mi);
1223 15262 clear_xstatecombos_mi(screen_handles, mi);
1224
1225 15262 handle_screen_load_trigger(screen_handles);
1226 15262 }
1227
1228 40981 std::optional<mapscr> load_temp_mapscr_and_apply_secrets(int32_t map, int32_t screen, int32_t layer, bool secrets, bool secrets_do_replay_comment)
1229 {
1230
2/4
✓ Branch 0 taken 40981 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40981 times.
40981 if (map < 0 || screen < 0)
1231 return std::nullopt;
1232
1233 40981 const mapscr* source = get_canonical_scr(map, screen);
1234
2/2
✓ Branch 0 taken 39256 times.
✓ Branch 1 taken 1725 times.
40981 if (!source->is_valid())
1235 1725 return std::nullopt;
1236
1237
2/2
✓ Branch 0 taken 7936 times.
✓ Branch 1 taken 31320 times.
39256 if (layer >= 0)
1238 {
1239
2/2
✓ Branch 0 taken 23994 times.
✓ Branch 1 taken 7326 times.
31320 if (source->layermap[layer] <= 0)
1240 23994 return std::nullopt;
1241
1242 7326 source = get_canonical_scr(source->layermap[layer] - 1, source->layerscreen[layer]);
1243
1/2
✓ Branch 0 taken 7326 times.
✗ Branch 1 not taken.
7326 if (!source->is_valid())
1244 return std::nullopt;
1245 7326 }
1246
1247
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 int flags = secrets ? game->maps[mapind(map, screen)] : 0;
1248 15262 mapscr scr = *source;
1249
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 apply_state_changes_to_screen(scr, map, screen, flags, secrets_do_replay_comment);
1250
1251
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 return scr;
1252 40981 }
1253
1254 14990 static int32_t MAPCOMBO3_impl(int32_t map, int32_t screen, int32_t layer, int32_t pos, bool secrets)
1255 {
1256
2/4
✓ Branch 0 taken 14990 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14990 times.
14990 if (map < 0 || screen < 0) return 0;
1257
1258
2/4
✓ Branch 0 taken 14990 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14990 times.
14990 if(pos>175 || pos < 0)
1259 return 0;
1260
1261 // TODO: consider caching this (invalidate on any modification via scripting, or anything
1262 // `apply_state_changes_to_screen` checks).
1263
4/5
✓ Branch 0 taken 4736 times.
✓ Branch 1 taken 10254 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4736 times.
✓ Branch 4 taken 10254 times.
19726 if (auto s = load_temp_mapscr_and_apply_secrets(map, screen, layer, secrets))
1264 4736 return s->data[pos];
1265
1266 10254 return 0;
1267 14990 }
1268
1269 // Read from the current temporary screens or, if (map, screen) is not loaded,
1270 // load that screen and apply the relevant secrets before evaluating the combo at that position.
1271 251448767 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets)
1272 {
1273 DCHECK_LAYER_NEG1_INDEX(layer);
1274 DCHECK(map >= 0 && screen >= 0);
1275
1276
2/2
✓ Branch 0 taken 251433777 times.
✓ Branch 1 taken 14990 times.
251448767 if (is_in_current_region(map, screen)) return MAPCOMBO2(layer, x, y);
1277
1278 // Screen is not in the current region, so we have to load and trigger some secrets.
1279 14990 int pos = COMBOPOS(x, y);
1280 14990 return MAPCOMBO3_impl(map, screen, layer, pos, secrets);
1281 251448767 }
1282
1283 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, rpos_t rpos, bool secrets)
1284 {
1285 DCHECK_LAYER_NEG1_INDEX(layer);
1286 DCHECK(map >= 0 && screen >= 0);
1287 DCHECK(is_valid_rpos(rpos));
1288
1289 if (is_in_current_region(map, screen)) return MAPCOMBO(get_rpos_handle(rpos, layer + 1));
1290
1291 // Screen is not currently loaded, so we have to load and trigger some secrets.
1292 return MAPCOMBO3_impl(map, screen, layer, RPOS_TO_POS(rpos), secrets);
1293 }
1294
1295 int32_t MAPCSET2(int32_t layer,int32_t x,int32_t y)
1296 {
1297 DCHECK_LAYER_NEG1_INDEX(layer);
1298 if (!is_in_world_bounds(x, y))
1299 return 0;
1300 if (layer == -1) return MAPCSET(x, y);
1301
1302 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1303 if (!rpos_handle.scr->is_valid()) return 0;
1304
1305 return rpos_handle.cset();
1306 }
1307
1308 102412209 int32_t MAPFLAG2(int32_t layer,int32_t x,int32_t y)
1309 {
1310 DCHECK_LAYER_NEG1_INDEX(layer);
1311
3/4
✓ Branch 0 taken 5385623 times.
✓ Branch 1 taken 97026586 times.
✓ Branch 2 taken 5385623 times.
✗ Branch 3 not taken.
102412209 if (!get_qr(qr_BUGGED_LAYERED_FLAGS) && (!is_in_world_bounds(x, y)))
1312 return 0;
1313
2/2
✓ Branch 0 taken 84274547 times.
✓ Branch 1 taken 18137662 times.
102412209 if (layer == -1) return MAPFLAG(x, y);
1314
1315 84274547 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1316
2/2
✓ Branch 0 taken 63730019 times.
✓ Branch 1 taken 20544528 times.
84274547 if (!rpos_handle.scr->is_valid()) return 0;
1317
1318 20544528 return rpos_handle.sflag();
1319 102412209 }
1320
1321 int32_t COMBOTYPE2(int32_t layer,int32_t x,int32_t y)
1322 {
1323 if(layer < 1)
1324 {
1325 for (int32_t i = layer+1; i <= 1; ++i)
1326 {
1327 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1328 {
1329 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1330 }
1331 else
1332 {
1333 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1334 }
1335 }
1336 }
1337 if(layer==-1) return COMBOTYPE(x,y);
1338
1339 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1340 if (!rpos_handle.scr->is_valid()) return 0;
1341
1342 return rpos_handle.ctype();
1343 }
1344
1345 // Returns the flag for the combo at the given position.
1346 // This is also known as an "inherent flag".
1347 100578885 int32_t MAPCOMBOFLAG2(int32_t layer,int32_t x,int32_t y)
1348 {
1349 DCHECK_LAYER_NEG1_INDEX(layer);
1350
2/2
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 100578597 times.
100578885 if (!is_in_world_bounds(x, y))
1351 288 return 0;
1352
2/2
✓ Branch 0 taken 84177975 times.
✓ Branch 1 taken 16400622 times.
100578597 if (layer == -1) return MAPCOMBOFLAG(x, y);
1353
1354 84177975 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1355
2/2
✓ Branch 0 taken 63748345 times.
✓ Branch 1 taken 20429630 times.
84177975 if (!rpos_handle.scr->is_valid()) return 0;
1356
1357 20429630 return rpos_handle.cflag();
1358 100578885 }
1359
1360 11728111 bool HASFLAG(int32_t flag, int32_t layer, rpos_t rpos)
1361 {
1362 DCHECK_LAYER_ZERO_INDEX(layer);
1363 11728111 auto rpos_handle = get_rpos_handle(rpos, layer);
1364
2/2
✓ Branch 0 taken 4498230 times.
✓ Branch 1 taken 7229881 times.
11728111 if (!rpos_handle.scr->is_valid()) return false;
1365
2/2
✓ Branch 0 taken 4565 times.
✓ Branch 1 taken 7225316 times.
7229881 if (rpos_handle.sflag() == flag) return true;
1366
2/2
✓ Branch 0 taken 37705 times.
✓ Branch 1 taken 7187611 times.
7225316 if (rpos_handle.cflag() == flag) return true;
1367 7187611 return false;
1368 11728111 }
1369
1370 1711529 bool HASFLAG_ANY(int32_t flag, rpos_t rpos)
1371 {
1372 DCHECK(is_valid_rpos(rpos));
1373
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1711529 times.
1711529 if (rpos > region_max_rpos) return false;
1374
1375
2/2
✓ Branch 0 taken 11728111 times.
✓ Branch 1 taken 1669259 times.
13397370 for(auto q = 0; q < 7; ++q)
1376 {
1377
2/2
✓ Branch 0 taken 42270 times.
✓ Branch 1 taken 11685841 times.
11728111 if(HASFLAG(flag, q, rpos))
1378 42270 return true;
1379 11685841 }
1380 1669259 return false;
1381 1711529 }
1382
1383 const char *screenstate_string[32] =
1384 {
1385 "Door Up", "Door Down", "Door Left", "Door Right", "Item", "Special Item", "Some Enemies Never Return",
1386 "Temporary No Return", "Lock Blocks", "Boss Lock Blocks", "Chests", "Locked Chests",
1387 "Boss Locked Chests", "Secrets", "Visited", "Light Beams",
1388 "All Enemies Don't Return", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>",
1389 "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>",
1390 };
1391
1392 36563 void eventlog_mapflags()
1393 {
1394 36563 std::ostringstream oss;
1395
1396 36563 int mi = mapind(cur_map, home_screen);
1397
1/2
✓ Branch 0 taken 36563 times.
✗ Branch 1 not taken.
36563 dword g = game->maps[mi];
1398
1399
2/4
✓ Branch 0 taken 36563 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36563 times.
✗ Branch 3 not taken.
36563 oss << fmt::format("Screen ({}, {:02X})", cur_map+1, home_screen);
1400
2/2
✓ Branch 0 taken 15711 times.
✓ Branch 1 taken 20852 times.
36563 if(g) // Main States
1401 {
1402 static const int order[] =
1403 {
1404 mSECRET, mITEM, mSPECIALITEM, mLOCKBLOCK, mBOSSLOCKBLOCK,
1405 mCHEST, mLOCKEDCHEST, mBOSSCHEST,
1406 mDOOR_UP, mDOOR_DOWN, mDOOR_LEFT, mDOOR_RIGHT,
1407 mNEVERRET, mTMPNORET, mLIGHTBEAM, mNO_ENEMIES_RETURN
1408 };
1409
1410
1/2
✓ Branch 0 taken 15711 times.
✗ Branch 1 not taken.
15711 oss << " [";
1411 15711 bool comma = false;
1412
2/2
✓ Branch 0 taken 15711 times.
✓ Branch 1 taken 251376 times.
267087 for(int fl : order)
1413 {
1414
2/2
✓ Branch 0 taken 9640 times.
✓ Branch 1 taken 241736 times.
251376 if(!(g&fl))
1415 241736 continue;
1416 9640 byte ind = byte(log2(double(fl)));
1417
2/2
✓ Branch 0 taken 2072 times.
✓ Branch 1 taken 7568 times.
9640 if(comma)
1418
1/2
✓ Branch 0 taken 2072 times.
✗ Branch 1 not taken.
2072 oss << ", ";
1419
1/2
✓ Branch 0 taken 9640 times.
✗ Branch 1 not taken.
9640 oss << screenstate_string[ind];
1420 9640 comma = true;
1421 }
1422
1/2
✓ Branch 0 taken 15711 times.
✗ Branch 1 not taken.
15711 oss << "]";
1423 15711 }
1424
3/4
✓ Branch 0 taken 36563 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 36507 times.
36563 if(game->xstates[mi]) // ExStates
1425 {
1426
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 oss << " Ex[";
1427 56 bool comma = false;
1428
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 1792 times.
1848 for(byte fl = 0; fl < 32; ++fl)
1429 {
1430
3/4
✓ Branch 0 taken 1792 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 77 times.
✓ Branch 3 taken 1715 times.
1792 if(game->xstates[mi] & (1<<fl))
1431 {
1432
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 56 times.
77 if(comma)
1433
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 oss << ", ";
1434
1/2
✓ Branch 0 taken 77 times.
✗ Branch 1 not taken.
77 oss << int(fl);
1435 77 comma = true;
1436 77 }
1437 1792 }
1438
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 oss << "]";
1439 56 }
1440 { // ExDoors
1441
2/2
✓ Branch 0 taken 36563 times.
✓ Branch 1 taken 146252 times.
182815 for(int q = 0; q < 4; ++q)
1442 {
1443 146252 bool comma = false;
1444
3/4
✓ Branch 0 taken 146252 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 146250 times.
✓ Branch 3 taken 2 times.
146252 if(auto v = game->xdoors[mi][q])
1445 {
1446
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(comma)
1447 oss << ",";
1448
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 else oss << " ExDoor";
1449
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 oss << "[" << dirstr[q];
1450
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 16 times.
18 for(int fl = 0; fl < 8; ++fl)
1451
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 3 times.
19 if(v & (1<<fl))
1452
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 oss << " " << int(fl);
1453
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 oss << "]";
1454 2 comma = true;
1455 2 }
1456 146252 }
1457 }
1458
2/4
✓ Branch 0 taken 36563 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 36563 times.
36563 Z_eventlog("%s\n", oss.str().c_str());
1459 36563 }
1460
1461 // set specific flag
1462 5932 void setmapflag(mapscr* scr, uint32_t flag)
1463 {
1464
2/2
✓ Branch 0 taken 5919 times.
✓ Branch 1 taken 13 times.
5932 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1465 5932 int mi = mapind(cur_map, scr->screen);
1466 5932 setmapflag_mi(scr, mi, flag);
1467 5932 }
1468 57 void setmapflag_homescr(uint32_t flag)
1469 {
1470 57 int mi = mapind(cur_map, home_screen);
1471 57 setmapflag_mi(origin_scr, mi, flag);
1472 57 }
1473 2065 void setmapflag_mi(int32_t mi, uint32_t flag)
1474 {
1475 2065 byte cscr = mi&((1<<7)-1);
1476 2065 byte cmap = (mi>>7);
1477 2065 mapscr* scr = origin_scr;
1478
2/2
✓ Branch 0 taken 835 times.
✓ Branch 1 taken 1230 times.
2065 if (is_in_current_region(cmap, cscr))
1479 1230 scr = get_scr(cmap, cscr);
1480
1481 2065 setmapflag_mi(scr, mi, flag);
1482 2065 }
1483
1484 8877 static void log_state_change(int map, int screen, std::string action)
1485 {
1486
6/6
✓ Branch 0 taken 1937 times.
✓ Branch 1 taken 6940 times.
✓ Branch 2 taken 996 times.
✓ Branch 3 taken 941 times.
✓ Branch 4 taken 352 times.
✓ Branch 5 taken 644 times.
8877 if (is_in_current_region(map, screen) || (map == cur_map && screen == home_screen))
1487 7292 Z_eventlog("[Map %d, Screen %02X (current)] %s\n", map + 1, screen, action.c_str());
1488 else
1489 1585 Z_eventlog("[Map %d, Screen %02X] %s\n", map + 1, screen, action.c_str());
1490 8877 }
1491
1492 8054 void setmapflag_mi(mapscr* scr, int32_t mi, uint32_t flag)
1493 {
1494 8054 byte cscr = mi&((1<<7)-1);
1495 8054 byte cmap = (mi>>7);
1496
1497 8054 double temp=log2((double)flag);
1498
1/2
✓ Branch 0 taken 8054 times.
✗ Branch 1 not taken.
8054 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1499 8054 const char* replay_state_string = state_string;
1500
2/2
✓ Branch 0 taken 7534 times.
✓ Branch 1 taken 520 times.
8054 if(temp == 6) replay_state_string = "No Return";
1501
1502
3/4
✓ Branch 0 taken 8054 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1596 times.
✓ Branch 3 taken 6458 times.
8054 if (replay_is_active() && !(game->maps[mi] & flag))
1503
1/2
✓ Branch 0 taken 6458 times.
✗ Branch 1 not taken.
6458 replay_step_comment(fmt::format("map {} scr {} flag {}", cmap, cscr, replay_state_string));
1504 8054 game->maps[mi] |= flag;
1505
1/2
✓ Branch 0 taken 8054 times.
✗ Branch 1 not taken.
8054 log_state_change(cmap, cscr, fmt::format("State set: {}", state_string));
1506
1507
2/2
✓ Branch 0 taken 2518 times.
✓ Branch 1 taken 5536 times.
8054 if((scr->nocarry&flag)!=flag)
1508 {
1509 5536 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1510 5536 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1511
1512 5536 std::vector<int32_t> done;
1513
2/2
✓ Branch 0 taken 5423 times.
✓ Branch 1 taken 113 times.
5536 bool looped = (nmap==cmap+1 && nscr==cscr);
1514
1515
6/6
✓ Branch 0 taken 458 times.
✓ Branch 1 taken 5485 times.
✓ Branch 2 taken 51 times.
✓ Branch 3 taken 407 times.
✓ Branch 4 taken 407 times.
✓ Branch 5 taken 5536 times.
5943 while((nmap!=0) && !looped && !(nscr>=128))
1516 {
1517
3/4
✓ Branch 0 taken 407 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 191 times.
✓ Branch 3 taken 216 times.
407 if(!(game->maps[((nmap-1)<<7)+nscr] & flag))
1518 {
1519
2/4
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
216 log_state_change(nmap, nscr, "State change carried over");
1520
2/4
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
216 if (replay_is_active())
1521
2/4
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
216 replay_step_comment(fmt::format("map {} scr {} flag {} carry", nmap, nscr, replay_state_string));
1522
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 game->maps[((nmap-1)<<7)+nscr] |= flag;
1523 216 }
1524
1525 407 cmap=nmap;
1526 407 cscr=nscr;
1527 407 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1528 407 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1529
1530
2/2
✓ Branch 0 taken 916 times.
✓ Branch 1 taken 407 times.
1323 for(auto it = done.begin(); it != done.end(); it++)
1531 {
1532
2/2
✓ Branch 0 taken 865 times.
✓ Branch 1 taken 51 times.
916 if(*it == ((nmap-1)<<7)+nscr)
1533 51 looped = true;
1534 916 }
1535
1536
1/2
✓ Branch 0 taken 407 times.
✗ Branch 1 not taken.
407 done.push_back(((nmap-1)<<7)+nscr);
1537 }
1538 5536 }
1539 8054 }
1540
1541 void unsetmapflag_home(uint32_t flag, bool anyflag)
1542 {
1543 int mi = mapind(cur_map, home_screen);
1544 unsetmapflag_mi(origin_scr, mi, flag, anyflag);
1545 }
1546
1547 void unsetmapflag(mapscr* scr, uint32_t flag, bool anyflag)
1548 {
1549 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1550 int mi = mapind(cur_map, scr->screen);
1551 unsetmapflag_mi(scr, mi, flag, anyflag);
1552 }
1553
1554 471 void unsetmapflag_mi(int32_t mi, uint32_t flag, bool anyflag)
1555 {
1556 471 byte cscr = mi&((1<<7)-1);
1557 471 byte cmap = (mi>>7);
1558 471 mapscr* scr = origin_scr;
1559
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if (is_in_current_region(cmap, cscr))
1560 11 scr = get_scr(cmap, cscr);
1561
1562 471 unsetmapflag_mi(scr, mi, flag, anyflag);
1563 471 }
1564
1565 471 void unsetmapflag_mi(mapscr* scr, int32_t mi, uint32_t flag, bool anyflag)
1566 {
1567 471 byte cscr = mi&((1<<7)-1);
1568 471 byte cmap = (mi>>7);
1569
1570
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if(anyflag)
1571 460 game->maps[mi] &= ~flag;
1572
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 else if(flag==mITEM || flag==mSPECIALITEM)
1573 {
1574 if(!(scr->flags4&fNOITEMRESET))
1575 game->maps[mi] &= ~flag;
1576 }
1577 11 else game->maps[mi] &= ~flag;
1578
1579 471 double temp=log2((double)flag);
1580
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1581
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 log_state_change(cmap, cscr, fmt::format("State unset: {}", state_string));
1582
1583
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 471 times.
471 if((scr->nocarry&flag)!=flag)
1584 {
1585 471 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1586 471 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1587
1588 471 std::vector<int32_t> done;
1589
2/2
✓ Branch 0 taken 466 times.
✓ Branch 1 taken 5 times.
471 bool looped = (nmap==cmap+1 && nscr==cscr);
1590
1591
6/6
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 465 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 471 times.
555 while((nmap!=0) && !looped && !(nscr>=128))
1592 {
1593
3/4
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 72 times.
84 if(game->maps[((nmap-1)<<7)+nscr] & flag)
1594 {
1595
2/4
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
72 log_state_change(nmap, nscr, "State change carried over");
1596
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 game->maps[((nmap-1)<<7)+nscr] &= ~flag;
1597 72 }
1598
1599 84 cmap=nmap;
1600 84 cscr=nscr;
1601 84 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1602 84 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1603
1604
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 546 times.
630 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1605 {
1606
2/2
✓ Branch 0 taken 540 times.
✓ Branch 1 taken 6 times.
546 if(*it == ((nmap-1)<<7)+nscr)
1607 6 looped = true;
1608 546 }
1609
1610
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 done.push_back(((nmap-1)<<7)+nscr);
1611 }
1612 471 }
1613 471 }
1614
1615 45525588 bool getmapflag(int32_t screen, uint32_t flag)
1616 {
1617
2/2
✓ Branch 0 taken 1164399 times.
✓ Branch 1 taken 44361189 times.
45525588 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1618 45525588 return (game->maps[mi] & flag) != 0;
1619 }
1620 6410868 bool getmapflag(mapscr* scr, uint32_t flag)
1621 {
1622
2/2
✓ Branch 0 taken 181526 times.
✓ Branch 1 taken 6229342 times.
6410868 int mi = mapind(scr->map, scr->screen >= 0x80 ? home_screen : scr->screen);
1623 6410868 return (game->maps[mi] & flag) != 0;
1624 }
1625
1626 57 void setxmapflag(int32_t screen, uint32_t flag)
1627 {
1628
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1629 57 setxmapflag_mi(mi, flag);
1630 57 }
1631 59 void setxmapflag_mi(int32_t mi, uint32_t flag)
1632 {
1633
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
59 if(game->xstates[mi] & flag) return;
1634 59 byte cscr = mi&((1<<7)-1);
1635 59 byte cmap = (mi>>7);
1636
1637 59 byte temp=(byte)log2((double)flag);
1638
1/2
✓ Branch 0 taken 59 times.
✗ Branch 1 not taken.
59 log_state_change(cmap, cscr, fmt::format("ExtraState set: {}", temp));
1639
1640 59 game->xstates[mi] |= flag;
1641
1642 59 mapscr* scr = origin_scr;
1643
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
59 if (is_in_current_region(cmap, cscr))
1644 59 scr = get_scr(cmap, cscr);
1645
1646
1/2
✓ Branch 0 taken 59 times.
✗ Branch 1 not taken.
59 if((scr->exstate_carry&flag)==flag)
1647 {
1648 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1649 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1650
1651 std::vector<int32_t> done;
1652 bool looped = (nmap==cmap+1 && nscr==cscr);
1653
1654 while((nmap!=0) && !looped && !(nscr>=128))
1655 {
1656 if(!(game->maps[((nmap-1)<<7)+nscr] & flag))
1657 {
1658 log_state_change(nmap, nscr, "ExState change carried over");
1659 if (replay_is_active())
1660 replay_step_comment(fmt::format("map {} scr {} exstate {} carry", nmap, nscr, temp));
1661 game->xstates[((nmap-1)<<7)+nscr] |= flag;
1662 }
1663
1664 cmap=nmap;
1665 cscr=nscr;
1666 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1667 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1668
1669 for(auto it = done.begin(); it != done.end(); it++)
1670 {
1671 if(*it == ((nmap-1)<<7)+nscr)
1672 looped = true;
1673 }
1674
1675 done.push_back(((nmap-1)<<7)+nscr);
1676 }
1677 }
1678 59 }
1679 2 void unsetxmapflag(int32_t screen, uint32_t flag)
1680 {
1681
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1682 2 unsetxmapflag_mi(mi, flag);
1683 2 }
1684 2 void unsetxmapflag_mi(int32_t mi, uint32_t flag)
1685 {
1686
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(!(game->xstates[mi] & flag)) return;
1687 1 byte cscr = mi&((1<<7)-1);
1688 1 byte cmap = (mi>>7);
1689 1 byte temp=(byte)log2((double)flag);
1690
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 log_state_change(cmap, cscr, fmt::format("ExtraState unset: {}", temp));
1691 1 game->xstates[mi] &= ~flag;
1692
1693 1 mapscr* scr = origin_scr;
1694
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (is_in_current_region(cmap, cscr))
1695 1 scr = get_scr(cmap, cscr);
1696
1697
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if((scr->exstate_carry&flag)==flag)
1698 {
1699 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1700 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1701
1702 std::vector<int32_t> done;
1703 bool looped = (nmap==cmap+1 && nscr==cscr);
1704
1705 while((nmap!=0) && !looped && !(nscr>=128))
1706 {
1707 if(game->maps[((nmap-1)<<7)+nscr] & flag)
1708 {
1709 log_state_change(nmap, nscr, "ExState change carried over");
1710 game->xstates[((nmap-1)<<7)+nscr] &= ~flag;
1711 }
1712
1713 cmap=nmap;
1714 cscr=nscr;
1715 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1716 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1717
1718 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1719 {
1720 if(*it == ((nmap-1)<<7)+nscr)
1721 looped = true;
1722 }
1723
1724 done.push_back(((nmap-1)<<7)+nscr);
1725 }
1726 }
1727 2 }
1728 82 bool getxmapflag(int32_t screen, uint32_t flag)
1729 {
1730
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 82 times.
82 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1731 82 return getxmapflag_mi(mi, flag);
1732 }
1733 bool getxmapflag(mapscr* scr, uint32_t flag)
1734 {
1735 int mi = mapind(scr->map, scr->screen >= 0x80 ? home_screen : scr->screen);
1736 return getxmapflag_mi(mi, flag);
1737 }
1738 488423648 bool getxmapflag_mi(int32_t mi, uint32_t flag)
1739 {
1740 488423648 return (game->xstates[mi] & flag) != 0;
1741 }
1742
1743 4 void setxdoor_mi(uint mi, uint dir, uint ind, bool state)
1744 {
1745
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
4 if(mi > game->xdoors.size() || dir > 3 || ind > 8)
1746 return;
1747
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(!(game->xdoors[mi][dir] & (1<<ind)) == !state)
1748 return;
1749
1750
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 SETFLAG(game->xdoors[mi][dir], 1<<ind, state);
1751
1752 4 int cscr = mi % MAPSCRSNORMAL;
1753 4 int cmap = mi / MAPSCRSNORMAL;
1754
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (state)
1755
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] set", dirstr[dir], ind));
1756 else
1757 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] unset", dirstr[dir], ind));
1758 4 }
1759 488423561 bool getxdoor_mi(uint mi, uint dir, uint ind)
1760 {
1761
3/6
✓ Branch 0 taken 488423561 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 488423561 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 488423561 times.
488423561 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1762 return false;
1763 488423561 return (game->xdoors[mi][dir] & (1<<ind));
1764 488423561 }
1765 9 bool getxdoor(int32_t screen, uint dir, uint ind)
1766 {
1767 9 int mi = mapind(cur_map, screen);
1768 9 return getxdoor_mi(mi,dir,ind);
1769 }
1770
1771 401 void set_doorstate_mi(uint mi, uint dir)
1772 {
1773
1/2
✓ Branch 0 taken 401 times.
✗ Branch 1 not taken.
401 if(dir >= 4)
1774 return;
1775 401 setmapflag_mi(mi, mDOOR_UP << dir);
1776
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 400 times.
401 if(auto di = nextscr_mi(mi, dir))
1777 400 setmapflag_mi(*di, mDOOR_UP << oppositeDir[dir]);
1778 401 }
1779 401 void set_doorstate(uint screen, uint dir)
1780 {
1781 401 int mi = mapind(cur_map, screen);
1782 401 set_doorstate_mi(mi, dir);
1783 401 }
1784
1785 2 void set_xdoorstate_mi(uint mi, uint dir, uint ind, bool state)
1786 {
1787
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1788 return;
1789 2 setxdoor_mi(mi, dir, ind, state);
1790
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(auto di = nextscr_mi(mi, dir))
1791 2 setxdoor_mi(*di, oppositeDir[dir], ind, state);
1792 2 }
1793
1794 2 void set_xdoorstate(int32_t screen,uint dir, uint ind, bool state)
1795 {
1796 2 int mi = mapind(cur_map, screen);
1797 2 set_xdoorstate_mi(mi, dir, ind, state);
1798 2 }
1799
1800 57 int32_t WARPCODE(int32_t dmap,int32_t screen,int32_t dw)
1801 // returns: -1 = not a warp screen
1802 // 0+ = warp screen code ( high byte=dmap, low byte=scr )
1803 {
1804 57 const mapscr *scr = get_canonical_scr(DMaps[dmap].map, screen);
1805
1806
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(scr->room!=rWARP)
1807 return -1;
1808
1809 57 int32_t ring=scr->catchall;
1810 57 int32_t size=QMisc.warp[ring].size;
1811
1812
1/2
✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
57 if(size==0)
1813 return -2;
1814
1815 57 int32_t index=-1;
1816
1817
2/2
✓ Branch 0 taken 289 times.
✓ Branch 1 taken 57 times.
346 for(int32_t i=0; i<size; i++)
1818
6/6
✓ Branch 0 taken 230 times.
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 173 times.
✓ Branch 3 taken 57 times.
✓ Branch 4 taken 173 times.
✓ Branch 5 taken 57 times.
289 if(dmap==QMisc.warp[ring].dmap[i] && screen==
1819 346 (QMisc.warp[ring].scr[i] + DMaps[dmap].xoff))
1820 57 index=i;
1821
1822
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(index==-1)
1823 return -3;
1824
1825 57 index = (index+dw)%size;
1826 57 return (QMisc.warp[ring].dmap[index] << 8) + QMisc.warp[ring].scr[index];
1827 57 }
1828
1829 15359754 void update_combo_cycling()
1830 {
1831 15359754 auto& combo_cache = combo_caches::can_cycle;
1832
1833 static int32_t newdata[176];
1834 static int32_t newcset[176];
1835 static bool initialized=false;
1836
1837 // Just a simple bit of optimization
1838
2/2
✓ Branch 0 taken 15359430 times.
✓ Branch 1 taken 324 times.
15359754 if(!initialized)
1839 {
1840
2/2
✓ Branch 0 taken 57024 times.
✓ Branch 1 taken 324 times.
57348 for(int32_t i=0; i<176; i++)
1841 {
1842 57024 newdata[i]=-1;
1843 57024 newcset[i]=-1;
1844 57024 }
1845
1846 324 initialized=true;
1847 324 }
1848
1849 15359754 std::set<uint16_t> restartanim;
1850
1851
1/2
✓ Branch 0 taken 15359754 times.
✗ Branch 1 not taken.
31108876 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
1852 15749122 int screen = scr->screen;
1853 int32_t x;
1854
1855
2/2
✓ Branch 0 taken 2771845472 times.
✓ Branch 1 taken 15749122 times.
2787594594 for(int32_t i=0; i<176; i++)
1856 {
1857 2771845472 x=scr->data[i];
1858 2771845472 auto& mini_cmb = combo_cache.minis[x];
1859
2/2
✓ Branch 0 taken 3282224 times.
✓ Branch 1 taken 2768563248 times.
2771845472 if (!mini_cmb.can_cycle)
1860 2768563248 continue;
1861
1862 3282224 newcombo const& cmb = combobuf[x];
1863
1864 //time to restart
1865
4/4
✓ Branch 0 taken 904477 times.
✓ Branch 1 taken 2377747 times.
✓ Branch 2 taken 475770 times.
✓ Branch 3 taken 428707 times.
3282224 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1866 {
1867 428707 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1868
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428707 times.
428707 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1869 428707 newdata[i] = c;
1870
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428687 times.
428707 if(!(cmb.animflags & AF_CYCLENOCSET))
1871
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428687 times.
428687 newcset[i] = cycle_under ? scr->undercset : cmb.nextcset;
1872
1873
2/2
✓ Branch 0 taken 427663 times.
✓ Branch 1 taken 1044 times.
428707 if(combobuf[c].animflags & AF_CYCLE)
1874 {
1875 1044 restartanim.insert(c);
1876 1044 }
1877 428707 }
1878 3282224 }
1879
1880 15749122 int rpos_base = (int)POS_TO_RPOS(0, region_scr_x, region_scr_y);
1881
2/2
✓ Branch 0 taken 2771845472 times.
✓ Branch 1 taken 15749122 times.
2787594594 for(int32_t i=0; i<176; i++)
1882 {
1883
2/2
✓ Branch 0 taken 428707 times.
✓ Branch 1 taken 2771416765 times.
2771845472 if(newdata[i]==-1)
1884 2771416765 continue;
1885
1886 428707 rpos_t rpos = (rpos_t)(rpos_base + i);
1887 428707 rpos_handle_t rpos_handle = {scr, scr, screen, 0, rpos, i};
1888 428707 screen_combo_modify_preroutine(rpos_handle);
1889 428707 scr->data[i]=newdata[i];
1890
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428687 times.
428707 if(newcset[i]>-1)
1891 428687 scr->cset[i]=newcset[i];
1892 428707 screen_combo_modify_postroutine(rpos_handle);
1893
1894 428707 newdata[i]=-1;
1895 428707 newcset[i]=-1;
1896 428707 }
1897
1898 15749122 word c = scr->numFFC();
1899
2/2
✓ Branch 0 taken 15749122 times.
✓ Branch 1 taken 454715631 times.
470464753 for(word i=0; i<c; i++)
1900 {
1901 454715631 ffcdata& ffc = scr->ffcs[i];
1902 454715631 auto& mini_cmb = combo_cache.minis[ffc.data];
1903
2/2
✓ Branch 0 taken 7727 times.
✓ Branch 1 taken 454707904 times.
454715631 if (!mini_cmb.can_cycle)
1904 454707904 continue;
1905
1906 7727 newcombo const& cmb = combobuf[ffc.data];
1907
1908 //time to restart
1909
4/4
✓ Branch 0 taken 1181 times.
✓ Branch 1 taken 6546 times.
✓ Branch 2 taken 856 times.
✓ Branch 3 taken 325 times.
7727 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1910 {
1911 325 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1912
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 325 times.
325 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1913 325 zc_ffc_set(ffc, c);
1914
2/2
✓ Branch 0 taken 217 times.
✓ Branch 1 taken 108 times.
325 if(!(cmb.animflags & AF_CYCLENOCSET))
1915
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 ffc.cset = cycle_under ? scr->undercset : cmb.nextcset;
1916
1917
2/2
✓ Branch 0 taken 265 times.
✓ Branch 1 taken 60 times.
325 if(combobuf[ffc.data].animflags & AF_CYCLE)
1918 {
1919 60 restartanim.insert(ffc.data);
1920 60 }
1921 325 }
1922 7727 }
1923
1924
2/2
✓ Branch 0 taken 8418399 times.
✓ Branch 1 taken 7330723 times.
15749122 if(get_qr(qr_CMBCYCLELAYERS))
1925 {
1926
2/2
✓ Branch 0 taken 43984338 times.
✓ Branch 1 taken 7330723 times.
51315061 for(int32_t j=1; j<=6; j++)
1927 {
1928 43984338 mapscr* layer_scr = get_scr_layer_valid(screen, j);
1929
2/2
✓ Branch 0 taken 13895276 times.
✓ Branch 1 taken 30089062 times.
43984338 if (!layer_scr)
1930 30089062 continue;
1931
1932
2/2
✓ Branch 0 taken 2445568576 times.
✓ Branch 1 taken 13895276 times.
2459463852 for(int32_t i=0; i<176; i++)
1933 {
1934 2445568576 x=layer_scr->data[i];
1935 2445568576 auto& mini_cmb = combo_cache.minis[x];
1936
2/2
✓ Branch 0 taken 2424344 times.
✓ Branch 1 taken 2443144232 times.
2445568576 if (!mini_cmb.can_cycle)
1937 2443144232 continue;
1938
1939 2424344 newcombo const& cmb = combobuf[x];
1940
1941 //time to restart
1942
4/4
✓ Branch 0 taken 67298 times.
✓ Branch 1 taken 2357046 times.
✓ Branch 2 taken 50626 times.
✓ Branch 3 taken 16672 times.
2424344 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1943 {
1944 16672 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1945
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16672 times.
16672 auto c = cycle_under ? layer_scr->undercombo : cmb.nextcombo;
1946 16672 newdata[i] = c;
1947
2/2
✓ Branch 0 taken 644 times.
✓ Branch 1 taken 16028 times.
16672 if(!(cmb.animflags & AF_CYCLENOCSET))
1948
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16028 times.
16028 newcset[i] = cycle_under ? layer_scr->undercset : cmb.nextcset;
1949 644 else newcset[i] = layer_scr->cset[i];
1950
1951
2/2
✓ Branch 0 taken 6689 times.
✓ Branch 1 taken 9983 times.
16672 if(combobuf[c].animflags & AF_CYCLE)
1952 {
1953 9983 restartanim.insert(c);
1954 9983 }
1955 16672 }
1956 2424344 }
1957
1958
2/2
✓ Branch 0 taken 2445568576 times.
✓ Branch 1 taken 13895276 times.
2459463852 for (int32_t i=0; i<176; i++)
1959 {
1960
2/2
✓ Branch 0 taken 2445551904 times.
✓ Branch 1 taken 16672 times.
2445568576 if(newdata[i]!=-1)
1961 {
1962 16672 layer_scr->data[i]=newdata[i];
1963
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16672 times.
16672 if(newcset[i]>-1)
1964 16672 layer_scr->cset[i]=newcset[i];
1965 16672 newdata[i]=-1;
1966 16672 newcset[i]=-1;
1967 16672 }
1968 2445568576 }
1969 13895276 }
1970 7330723 }
1971 15749122 });
1972
1973
2/2
✓ Branch 0 taken 15359754 times.
✓ Branch 1 taken 2661 times.
15362415 for (auto i : restartanim)
1974 {
1975 2661 combobuf[i].tile = combobuf[i].o_tile;
1976 2661 combobuf[i].cur_frame=0;
1977 2661 combobuf[i].aclk = 0;
1978
1/2
✓ Branch 0 taken 2661 times.
✗ Branch 1 not taken.
2661 combo_caches::drawing.refresh(i);
1979 }
1980 15359754 }
1981
1982 1426206757 bool iswater_type(int32_t type)
1983 {
1984 // return type==cOLD_WATER || type==cSWIMWARP || type==cDIVEWARP || type==cDIVEWARPB || type==cDIVEWARPC || type==cDIVEWARPD || type==cSWIMWARPB || type==cSWIMWARPC || type==cSWIMWARPD;
1985 1426206757 return (combo_class_buf[type].water!=0);
1986 }
1987
1988 bool iswater(int32_t combo)
1989 {
1990 return iswater_type(combobuf[combo].type) && !DRIEDLAKE;
1991 }
1992 5280776 int32_t iswaterexzq(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck)
1993 {
1994 5280776 return iswaterex(combo, map, screen, layer, x, y, secrets, fullcheck, LayerCheck);
1995 }
1996
1997 // (x, y) are world coordinates
1998 68242598 int32_t iswaterex_z3(int32_t combo, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
1999 {
2000
8/8
✓ Branch 0 taken 68194735 times.
✓ Branch 1 taken 47863 times.
✓ Branch 2 taken 68152875 times.
✓ Branch 3 taken 41860 times.
✓ Branch 4 taken 68083392 times.
✓ Branch 5 taken 69483 times.
✓ Branch 6 taken 63405 times.
✓ Branch 7 taken 68019987 times.
68242598 if (x<0 || x>=world_w || y<0 || y>=world_h)
2001 222611 return false;
2002
2003 68019987 return iswaterex(combo, cur_map, cur_screen, layer, x, y, secrets, fullcheck, LayerCheck, ShallowCheck, hero, out_handle);
2004 68242598 }
2005
2006 148713438 int32_t iswaterex(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
2007 {
2008 DCHECK_LAYER_NEG1_INDEX(layer);
2009 //Honestly, fullcheck is kinda useless... I made this function back when I thought it was checking the entire combo and not just a glorified x/y value.
2010 //Fullcheck makes no sense to ever be on, but hey I guess it's here in case you ever need it...
2011
2012 //Oh hey, Zoras might actually need it. Nevermind, this had a use!
2013
2/2
✓ Branch 0 taken 108796329 times.
✓ Branch 1 taken 39917109 times.
148713438 if (get_qr(qr_SMARTER_WATER))
2014 {
2015
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 108796329 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
108796329 if (DRIEDLAKE) return 0;
2016
5/6
✓ Branch 0 taken 32452741 times.
✓ Branch 1 taken 76343588 times.
✓ Branch 2 taken 6533834 times.
✓ Branch 3 taken 25918907 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6533834 times.
108796329 if (LayerCheck && (get_qr(qr_WATER_ON_LAYER_1) || get_qr(qr_WATER_ON_LAYER_2))) //LayerCheck is a bit dumber, but it lets me add this QR without having to replace all calls, again.
2017 {
2018
2/2
✓ Branch 0 taken 75585129 times.
✓ Branch 1 taken 24828894 times.
100414023 for (int32_t m = layer; m <= 1; m++)
2019 {
2020
5/6
✓ Branch 0 taken 49666222 times.
✓ Branch 1 taken 25918907 times.
✓ Branch 2 taken 24836109 times.
✓ Branch 3 taken 24830113 times.
✓ Branch 4 taken 24830113 times.
✗ Branch 5 not taken.
100415242 if (m < 0 || m == 0 && get_qr(qr_WATER_ON_LAYER_1)
2021
1/2
✓ Branch 0 taken 24830113 times.
✗ Branch 1 not taken.
49666222 || m == 1 && get_qr(qr_WATER_ON_LAYER_2))
2022 {
2023 75585129 int32_t checkwater = iswaterex(combo, map, screen, m, x, y, secrets, fullcheck, false, ShallowCheck);
2024
2/2
✓ Branch 0 taken 74495116 times.
✓ Branch 1 taken 1090013 times.
75585129 if (checkwater > 0)
2025 {
2026
2/2
✓ Branch 0 taken 999753 times.
✓ Branch 1 taken 90260 times.
1090013 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, m+1);
2027 1090013 return checkwater;
2028 }
2029 74495116 }
2030 74495116 }
2031 24828894 return 0;
2032 }
2033 else
2034 {
2035
2/2
✓ Branch 0 taken 82901066 times.
✓ Branch 1 taken 78349407 times.
161250473 for(int32_t i=(fullcheck?3:0); i>=0; i--)
2036 {
2037 82901066 int32_t tx2=((i&2)<<2)+x;
2038 82901066 int32_t ty2=((i&1)<<3)+y;
2039 82901066 int32_t b = i; //Originally b was not needed and I read off i, but then I added the boolean for fullcheck.
2040 //In which case it's just easier to change b if fullcheck is false instead of changing i and potentially screwing up the for loop.
2041
2/2
✓ Branch 0 taken 36073 times.
✓ Branch 1 taken 82864993 times.
82901066 if (!fullcheck)
2042 {
2043 82864993 tx2 = x;
2044 82864993 ty2 = y;
2045
2/2
✓ Branch 0 taken 45333458 times.
✓ Branch 1 taken 37531535 times.
82864993 if(tx2&8) b+=2;
2046
2/2
✓ Branch 0 taken 39271171 times.
✓ Branch 1 taken 43593822 times.
82864993 if(ty2&8) b+=1;
2047 82864993 }
2048
2/2
✓ Branch 0 taken 171773123 times.
✓ Branch 1 taken 80457651 times.
252230774 for (int32_t m = layer; m <= 1; m++)
2049 {
2050 171773123 newcombo const& cmb = combobuf[MAPCOMBO3(map, screen, m,tx2,ty2, true)];
2051
3/6
✓ Branch 0 taken 169585620 times.
✓ Branch 1 taken 2187503 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 169585620 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
171773123 if (hero && cmb.dive_under_level && (Hero.get_standing_z_state() <= -cmb.dive_under_level))
2052 continue; // dive under this layer
2053
2054
2/2
✓ Branch 0 taken 17728431 times.
✓ Branch 1 taken 154044692 times.
171773123 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2055 {
2056
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17728431 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17728431 if (cmb.type == cBRIDGE && !(cmb.walk&(1<<b)))
2057 {
2058 return 0;
2059 }
2060 17728431 }
2061 else
2062 {
2063
4/4
✓ Branch 0 taken 253102 times.
✓ Branch 1 taken 153791590 times.
✓ Branch 2 taken 51152 times.
✓ Branch 3 taken 201950 times.
154044692 if (cmb.type == cBRIDGE && (cmb.walk&(0x10<<b)))
2064 {
2065 201950 return 0;
2066 }
2067 }
2068
2/2
✓ Branch 0 taken 17728431 times.
✓ Branch 1 taken 153842742 times.
171571173 if (get_qr(qr_NO_SOLID_SWIM))
2069 {
2070
8/14
✓ Branch 0 taken 51152 times.
✓ Branch 1 taken 153791590 times.
✓ Branch 2 taken 51152 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2241465 times.
✓ Branch 5 taken 151550125 times.
✓ Branch 6 taken 34499 times.
✓ Branch 7 taken 2206966 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 34499 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
153842742 if ((cmb.type != cBRIDGE || (!get_qr(qr_OLD_BRIDGE_COMBOS) && !(cmb.walk&(0x10<<b)))) && (cmb.walk&(1<<b)) && !((cmb.usrflags&cflag4) && cmb.type == cWATER && (cmb.walk&(0x10<<b)) && ShallowCheck))
2071 2241465 return 0;
2072 151601277 }
2073
3/6
✓ Branch 0 taken 497938 times.
✓ Branch 1 taken 168831770 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 497938 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
169329708 if (iswater_type(cmb.type) && (cmb.walk&(1<<b)) && ((cmb.usrflags&cflag3) || (cmb.usrflags&cflag4)
2074 || (hero && current_item(itype_flippers) < cmb.c_attributes[8])
2075 || (hero && ((cmb.usrflags&cflag1) && !(itemsbuf[current_item_id(itype_flippers)].flags & item_flag3)))))
2076 {
2077 if (!(ShallowCheck && (cmb.walk&(1<<b)) && (cmb.usrflags&cflag4))) return 0;
2078 }
2079 169329708 }
2080
2081 80457651 bool found_land = false;
2082 80457651 bool found_water = false;
2083 ffc_handle_t water_ffc_handle;
2084 223221348 find_ffc([&](const ffc_handle_t& ffc_handle) {
2085
2/2
✓ Branch 0 taken 141976906 times.
✓ Branch 1 taken 786791 times.
142763697 if (ffcIsAt(ffc_handle, tx2, ty2))
2086 {
2087 786791 auto ty = ffc_handle.ctype();
2088
3/4
✓ Branch 0 taken 786791 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 592941 times.
✓ Branch 3 taken 193850 times.
786791 bool is_water_type = combo_class_buf[ty].water || (ShallowCheck && ty == cSHALLOWWATER);
2089
2090
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 786791 times.
786791 if (!is_water_type)
2091 {
2092 786791 found_land = true;
2093 786791 return true;
2094 }
2095 else
2096 {
2097 // A later FFC might be land, in which case the water will be ignored.
2098 if (!found_water)
2099 {
2100 water_ffc_handle = ffc_handle;
2101 found_water = true;
2102 }
2103 }
2104 }
2105
2106 141976906 return false;
2107 142763697 });
2108
2109
2/2
✓ Branch 0 taken 79670860 times.
✓ Branch 1 taken 786791 times.
80457651 if (found_land) return 0;
2110
2111
3/4
✓ Branch 0 taken 79647216 times.
✓ Branch 1 taken 23644 times.
✓ Branch 2 taken 79647216 times.
✗ Branch 3 not taken.
79670860 if (!i && found_water)
2112 {
2113 if (out_handle) *out_handle = water_ffc_handle;
2114 return water_ffc_handle.data();
2115 }
2116
2117 79670860 int32_t checkcombo = MAPCOMBO3(map, screen, layer, tx2, ty2, secrets);
2118
2/2
✓ Branch 0 taken 79626366 times.
✓ Branch 1 taken 44494 times.
79670860 if (!(combobuf[checkcombo].walk&(1<<(b+4)))) return 0;
2119
7/12
✓ Branch 0 taken 79196344 times.
✓ Branch 1 taken 430022 times.
✓ Branch 2 taken 17016076 times.
✓ Branch 3 taken 62180268 times.
✓ Branch 4 taken 16191206 times.
✓ Branch 5 taken 824870 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 16191206 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
79626366 if (iswater_type(combobuf[checkcombo].type)||(ShallowCheck && (combobuf[checkcombo].type == cSHALLOWWATER || (iswater_type(combobuf[checkcombo].type) && (combobuf[checkcombo].walk&(1<<b)) && (combobuf[checkcombo].usrflags&cflag4)))))
2120 {
2121
2/2
✓ Branch 0 taken 1577 times.
✓ Branch 1 taken 1253315 times.
1254892 if (i == 0)
2122 {
2123
2/2
✓ Branch 0 taken 1249305 times.
✓ Branch 1 taken 4010 times.
1253315 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(tx2, ty2, layer+1);
2124 1253315 return checkcombo;
2125 }
2126 1577 }
2127 78373051 }
2128 78349407 return 0;
2129 }
2130 }
2131 else
2132 {
2133 39917109 int32_t b = 0;
2134
2/2
✓ Branch 0 taken 20704060 times.
✓ Branch 1 taken 19213049 times.
39917109 if(x&8) b+=2;
2135
2/2
✓ Branch 0 taken 15524133 times.
✓ Branch 1 taken 24392976 times.
39917109 if(y&8) b+=1;
2136
1/2
✓ Branch 0 taken 39917109 times.
✗ Branch 1 not taken.
39917109 if (get_qr(qr_NO_SOLID_SWIM))
2137 {
2138 if (combobuf[combo].walk&(1<<b))
2139 {
2140 return 0;
2141 }
2142 }
2143
1/2
✓ Branch 0 taken 39917109 times.
✗ Branch 1 not taken.
39917109 if (!(combobuf[combo].walk&(1<<(b+4)))) return 0;
2144
8/8
✓ Branch 0 taken 38150901 times.
✓ Branch 1 taken 1766208 times.
✓ Branch 2 taken 167945 times.
✓ Branch 3 taken 37982956 times.
✓ Branch 4 taken 2129 times.
✓ Branch 5 taken 1778552 times.
✓ Branch 6 taken 163774 times.
✓ Branch 7 taken 165477 times.
39917109 if((iswater_type(combobuf[combo].type) || (ShallowCheck && combobuf[combo].type == cSHALLOWWATER)) && !DRIEDLAKE)
2145 {
2146
2/2
✓ Branch 0 taken 1817922 times.
✓ Branch 1 taken 126107 times.
1944029 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, 0); //NOTE: This is only correct assuming 'combo' is 'MAPCOMBO(x,y)'
2147 1944029 return combo;
2148 }
2149 38146730 return 0;
2150 }
2151 148887088 }
2152
2153 354 bool isdamage_type(int32_t type)
2154 {
2155
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 28 times.
354 switch(type)
2156 {
2157 case cDAMAGE1: case cDAMAGE2: case cDAMAGE3: case cDAMAGE4:
2158 case cDAMAGE5: case cDAMAGE6: case cDAMAGE7:
2159 28 return true;
2160 }
2161 326 return false;
2162 354 }
2163
2164 2230870883 bool ispitfall_type(int32_t type)
2165 {
2166 2230870883 return combo_class_buf[type].pit != 0;
2167 }
2168
2169 2230870883 bool ispitfall(int32_t combo)
2170 {
2171 2230870883 return ispitfall_type(combobuf[combo].type);
2172 }
2173
2174 138874824 bool ispitfall(int32_t x, int32_t y)
2175 {
2176
2/2
✓ Branch 0 taken 1303545 times.
✓ Branch 1 taken 137571279 times.
138874824 if(int32_t c = MAPFFCOMBO(x,y))
2177 {
2178 1303545 return ispitfall(c) ? true : false;
2179 }
2180 137571279 int32_t c = MAPCOMBOL(2,x,y);
2181
2/2
✓ Branch 0 taken 77 times.
✓ Branch 1 taken 137571202 times.
137571279 if(ispitfall(c)) return true;
2182
2/2
✓ Branch 0 taken 122671419 times.
✓ Branch 1 taken 14899783 times.
137571202 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2183 {
2184
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 122671419 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
122671419 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return false;
2185 122671419 }
2186 else
2187 {
2188
3/4
✓ Branch 0 taken 16381 times.
✓ Branch 1 taken 14883402 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 16381 times.
14899783 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return false;
2189 }
2190 137554821 c = MAPCOMBOL(1,x,y);
2191
2/2
✓ Branch 0 taken 19968 times.
✓ Branch 1 taken 137534853 times.
137554821 if(ispitfall(c)) return true;
2192
2193
2/2
✓ Branch 0 taken 122671419 times.
✓ Branch 1 taken 14863434 times.
137534853 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2194 {
2195
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 122671419 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
122671419 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return false;
2196 122671419 }
2197 else
2198 {
2199
4/4
✓ Branch 0 taken 16533 times.
✓ Branch 1 taken 14846901 times.
✓ Branch 2 taken 12238 times.
✓ Branch 3 taken 4295 times.
14863434 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return false;
2200 }
2201 137522615 c = MAPCOMBO(x,y);
2202
2/2
✓ Branch 0 taken 59030 times.
✓ Branch 1 taken 137463585 times.
137522615 if(ispitfall(c)) return true;
2203 137463585 return false;
2204 138874824 }
2205
2206 612069861 int32_t getpitfall(int32_t x, int32_t y) //Return the highest-layer active pit combo at the given position
2207 {
2208
2/2
✓ Branch 0 taken 9485176 times.
✓ Branch 1 taken 602584685 times.
612069861 if(int32_t c = MAPFFCOMBO(x,y))
2209 {
2210
2/2
✓ Branch 0 taken 845 times.
✓ Branch 1 taken 9484331 times.
9485176 return ispitfall(c) ? c : 0;
2211 }
2212 602584685 int32_t c = MAPCOMBOL(2,x,y);
2213
2/2
✓ Branch 0 taken 1362 times.
✓ Branch 1 taken 602583323 times.
602584685 if(ispitfall(c)) return c;
2214
2215
2/2
✓ Branch 0 taken 532722485 times.
✓ Branch 1 taken 69860838 times.
602583323 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2216 {
2217
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532722485 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532722485 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return 0;
2218 532722485 }
2219 else
2220 {
2221
3/4
✓ Branch 0 taken 81108 times.
✓ Branch 1 taken 69779730 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 81108 times.
69860838 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return 0;
2222 }
2223 602502215 c = MAPCOMBOL(1,x,y);
2224
2/2
✓ Branch 0 taken 25192 times.
✓ Branch 1 taken 602477023 times.
602502215 if(ispitfall(c)) return c;
2225
2226
2/2
✓ Branch 0 taken 532722485 times.
✓ Branch 1 taken 69754538 times.
602477023 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2227 {
2228
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532722485 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532722485 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return 0;
2229 532722485 }
2230 else
2231 {
2232
4/4
✓ Branch 0 taken 171385 times.
✓ Branch 1 taken 69583153 times.
✓ Branch 2 taken 130757 times.
✓ Branch 3 taken 40628 times.
69754538 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return 0;
2233 }
2234 602346266 c = MAPCOMBO(x,y);
2235
2/2
✓ Branch 0 taken 200269 times.
✓ Branch 1 taken 602145997 times.
602346266 if(ispitfall(c)) return c;
2236 602145997 return 0;
2237 612069861 }
2238 99 optional<combined_handle_t> get_pitfall_handle(int32_t x, int32_t y) //Return the highest-layer active pit combo handle at the given position
2239 {
2240
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 98 times.
99 if(int32_t c = MAPFFCOMBO(x,y))
2241 {
2242
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 return ispitfall(c) ? getFFCAt(x,y) : nullopt;
2243 }
2244 98 int32_t c = MAPCOMBOL(2,x,y);
2245
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 97 times.
98 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 2);
2246
2247
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 91 times.
97 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2248 {
2249
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1))
2250 return nullopt;
2251 6 }
2252 else
2253 {
2254
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 91 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
91 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1))
2255 return nullopt;
2256 }
2257 97 c = MAPCOMBOL(1,x,y);
2258
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 85 times.
97 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 1);
2259
2260
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 79 times.
85 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2261 {
2262
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0))
2263 return nullopt;
2264 6 }
2265 else
2266 {
2267
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 79 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
79 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0))
2268 return nullopt;
2269 }
2270 85 c = MAPCOMBO(x,y);
2271
1/2
✓ Branch 0 taken 85 times.
✗ Branch 1 not taken.
85 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 0);
2272 return nullopt;
2273 99 }
2274 11918937 bool check_icy(newcombo const& cmb, int type)
2275 {
2276
2/2
✓ Branch 0 taken 11918772 times.
✓ Branch 1 taken 165 times.
11918937 if(cmb.type != cICY)
2277 11918772 return false;
2278
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 165 times.
165 switch(type)
2279 {
2280 case ICY_BLOCK:
2281 return cmb.usrflags&cflag1;
2282 case ICY_PLAYER:
2283 165 return cmb.usrflags&cflag2;
2284 }
2285 return false;
2286 11918937 }
2287 3978929 int get_icy(int x, int y, int type)
2288 {
2289 3978929 int32_t c = MAPCOMBOL(2,x,y);
2290
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3978929 times.
3978929 if(check_icy(combobuf[c], type)) return c;
2291
2292 3978929 int screen = get_screen_for_world_xy(x, y);
2293
2294 3978929 mapscr* scr = get_scr_layer_valid(screen, 2);
2295
2/2
✓ Branch 0 taken 33173 times.
✓ Branch 1 taken 3945756 times.
3978929 if (scr)
2296 {
2297
2/2
✓ Branch 0 taken 516 times.
✓ Branch 1 taken 3945240 times.
3945756 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2298 {
2299
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 516 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
516 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2300 516 }
2301 else
2302 {
2303
3/4
✓ Branch 0 taken 6663 times.
✓ Branch 1 taken 3938577 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6663 times.
3945240 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2304 }
2305 3939093 }
2306 3972266 c = MAPCOMBOL(1,x,y);
2307
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3972266 times.
3972266 if(check_icy(combobuf[c], type)) return c;
2308
2309 3972266 scr = get_scr_layer_valid(screen, 1);
2310
2/2
✓ Branch 0 taken 15312 times.
✓ Branch 1 taken 3956954 times.
3972266 if (scr)
2311 {
2312
2/2
✓ Branch 0 taken 1934 times.
✓ Branch 1 taken 3955020 times.
3956954 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2313 {
2314
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1934 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1934 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2315 1934 }
2316 else
2317 {
2318
3/4
✓ Branch 0 taken 4689 times.
✓ Branch 1 taken 3950331 times.
✓ Branch 2 taken 4689 times.
✗ Branch 3 not taken.
3955020 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2319 }
2320 3952265 }
2321 3967577 c = MAPCOMBO(x,y);
2322
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3967577 times.
3967577 if(check_icy(combobuf[c], type)) return c;
2323 3967577 return 0;
2324 3978929 }
2325
2326 13260763 static bool checkSV(int32_t x, int32_t y, int32_t flag)
2327 {
2328
8/8
✓ Branch 0 taken 13253965 times.
✓ Branch 1 taken 6798 times.
✓ Branch 2 taken 13245099 times.
✓ Branch 3 taken 8866 times.
✓ Branch 4 taken 13233467 times.
✓ Branch 5 taken 11632 times.
✓ Branch 6 taken 434748 times.
✓ Branch 7 taken 12798719 times.
13260763 if(x<0 || x>=world_w || y<0 || y>=world_h)
2329 462044 return false;
2330
2331 12798719 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
2332
2/4
✓ Branch 0 taken 12798719 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12798719 times.
12798719 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2333 return true;
2334
2335 12798719 change_rpos_handle_layer(rpos_handle, 1);
2336
2/2
✓ Branch 0 taken 7571070 times.
✓ Branch 1 taken 5227649 times.
12798719 if (rpos_handle.scr->is_valid())
2337
3/4
✓ Branch 0 taken 5227649 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3279 times.
✓ Branch 3 taken 5224370 times.
5227649 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2338 3279 return true;
2339
2340 12795440 change_rpos_handle_layer(rpos_handle, 2);
2341
2/2
✓ Branch 0 taken 10854872 times.
✓ Branch 1 taken 1940568 times.
12795440 if (rpos_handle.scr->is_valid())
2342
3/4
✓ Branch 0 taken 1940568 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 81 times.
✓ Branch 3 taken 1940487 times.
1940568 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2343 81 return true;
2344
2345 12795359 return false;
2346 13260763 }
2347
2348 6694564 bool isSVLadder(int32_t x, int32_t y)
2349 {
2350 6694564 return checkSV(x, y, mfSIDEVIEWLADDER);
2351 }
2352
2353 6566199 bool isSVPlatform(int32_t x, int32_t y)
2354 {
2355 6566199 return checkSV(x, y, mfSIDEVIEWPLATFORM);
2356 }
2357
2358 6566199 bool checkSVLadderPlatform(int32_t x, int32_t y)
2359 {
2360
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6566199 times.
✓ Branch 2 taken 6564361 times.
✓ Branch 3 taken 1838 times.
6566199 return isSVPlatform(x,y) || (isSVLadder(x,y) && !isSVLadder(x,y-16));
2361 }
2362
2363 4206 bool isstepable(int32_t combo) //can use ladder on it
2364 {
2365
2/2
✓ Branch 0 taken 4200 times.
✓ Branch 1 taken 6 times.
4206 if(combo_class_buf[combobuf[combo].type].ladder_pass) return true;
2366
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(combo_class_buf[combobuf[combo].type].pit)
2367 {
2368 if(combobuf[combo].usrflags&cflag4)
2369 {
2370 int32_t ldrid = current_item_id(itype_ladder);
2371 return (ldrid > -1 && itemsbuf[ldrid].flags & item_flag1);
2372 }
2373 }
2374 6 return false;
2375 4206 }
2376
2377 33016 bool isHSGrabbable(newcombo const& cmb)
2378 {
2379
2/2
✓ Branch 0 taken 377 times.
✓ Branch 1 taken 32639 times.
33016 if(cmb.type == cHSGRAB) return true;
2380 32639 return cmb.genflags & cflag1;
2381 33016 }
2382
2383 954 bool isSwitchHookable(newcombo const& cmb)
2384 {
2385
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 822 times.
954 if(cmb.type == cSWITCHHOOK) return true;
2386 822 return cmb.genflags & cflag2;
2387 954 }
2388
2389 62207 bool check_hshot(int32_t layer, int32_t x, int32_t y, bool switchhook, rpos_t *out_rpos, ffcdata **out_ffc)
2390 {
2391 62207 rpos_t cpos = rpos_t::None;
2392
2/2
✓ Branch 0 taken 65056 times.
✓ Branch 1 taken 127263 times.
62207 if(out_rpos)
2393 {
2394 127263 int32_t id = MAPCOMBO2(layer-1,x,y);
2395
2/2
✓ Branch 0 taken 29204 times.
✓ Branch 1 taken 98059 times.
127263 if(id > 0)
2396 {
2397 98059 newcombo const& cmb = combobuf[id];
2398
4/4
✓ Branch 0 taken 32974 times.
✓ Branch 1 taken 65085 times.
✓ Branch 2 taken 32528 times.
✓ Branch 3 taken 32557 times.
98059 cpos = (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb)) ? COMBOPOS_REGION(x,y) : rpos_t::None;
2399 33003 }
2400 62207 }
2401
2402 127263 ffcdata* ffc = nullptr;
2403
4/4
✓ Branch 0 taken 28531 times.
✓ Branch 1 taken 98732 times.
✓ Branch 2 taken 24996 times.
✓ Branch 3 taken 3535 times.
127263 if (out_ffc && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2404 {
2405 10645 for_some_ffcs([&](const ffc_handle_t& ffc_handle) {
2406
2/2
✓ Branch 0 taken 6995 times.
✓ Branch 1 taken 115 times.
7110 if (ffcIsAt(ffc_handle, x, y))
2407 {
2408 115 auto& cmb = ffc_handle.combo();
2409
4/4
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 73 times.
✓ Branch 2 taken 37 times.
✓ Branch 3 taken 36 times.
115 if (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb))
2410 {
2411 79 ffc = ffc_handle.ffc;
2412 79 return false;
2413 }
2414 36 }
2415 7031 return true;
2416 7038 });
2417 3535 }
2418
2419
4/4
✓ Branch 0 taken 62207 times.
✓ Branch 1 taken 65056 times.
✓ Branch 2 taken 446 times.
✓ Branch 3 taken 61761 times.
127263 if (out_rpos && cpos != rpos_t::None) *out_rpos = cpos;
2420
4/4
✓ Branch 0 taken 28531 times.
✓ Branch 1 taken 98732 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 28524 times.
127263 if (out_ffc && ffc) *out_ffc = ffc;
2421
2/2
✓ Branch 0 taken 65502 times.
✓ Branch 1 taken 61761 times.
127263 return (cpos != rpos_t::None || ffc);
2422 }
2423
2424 5199 bool ishookshottable(int32_t bx, int32_t by)
2425 {
2426
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5199 times.
5199 if(!_walkflag(bx,by,1))
2427 return true;
2428
2429
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5191 times.
5199 if (collide_object(bx, by, 1, 1))
2430 8 return false;
2431
2432 5191 bool ret = true;
2433
2/2
✓ Branch 0 taken 15573 times.
✓ Branch 1 taken 1904 times.
17477 for(int32_t i=2; i>=0; i--)
2434 {
2435 15573 int32_t c = MAPCOMBO2(i-1,bx,by);
2436 15573 int32_t t = combobuf[c].type;
2437
2438
6/6
✓ Branch 0 taken 5191 times.
✓ Branch 1 taken 10382 times.
✓ Branch 2 taken 3857 times.
✓ Branch 3 taken 1334 times.
✓ Branch 4 taken 1904 times.
✓ Branch 5 taken 1953 times.
15573 if(i == 0 && (t == cHOOKSHOTONLY || t == cLADDERHOOKSHOT)) return true;
2439
2440
3/4
✓ Branch 0 taken 11333 times.
✓ Branch 1 taken 953 times.
✓ Branch 2 taken 953 times.
✗ Branch 3 not taken.
13239 bool dried = (iswater_type(t) && DRIEDLAKE);
2441
2442 12286 int32_t b=1;
2443
2444
2/2
✓ Branch 0 taken 6112 times.
✓ Branch 1 taken 6174 times.
12286 if(bx&8) b<<=2;
2445
2446
2/2
✓ Branch 0 taken 3853 times.
✓ Branch 1 taken 8433 times.
12286 if(by&8) b<<=1;
2447
2448
7/8
✓ Branch 0 taken 2098 times.
✓ Branch 1 taken 10188 times.
✓ Branch 2 taken 2098 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1115 times.
✓ Branch 5 taken 983 times.
✓ Branch 6 taken 75 times.
✓ Branch 7 taken 908 times.
12286 if(combobuf[c].walk&b && !dried && !(combo_class_buf[t].ladder_pass && t!=cLADDERONLY) && t!=cHOOKSHOTONLY)
2449 908 ret = false;
2450 12286 }
2451
2452 1904 return ret;
2453 5199 }
2454
2455 11108 bool reveal_hidden_stairs(mapscr *s, int32_t screen, bool redraw)
2456 {
2457
4/4
✓ Branch 0 taken 10529 times.
✓ Branch 1 taken 579 times.
✓ Branch 2 taken 10529 times.
✓ Branch 3 taken 579 times.
11108 if((s->stairx || s->stairy) && s->secretcombo[sSTAIRS])
2458 {
2459 579 int pos = COMBOPOS(s->stairx,s->stairy);
2460 579 s->data[pos] = s->secretcombo[sSTAIRS];
2461 579 s->cset[pos] = s->secretcset[sSTAIRS];
2462 579 s->sflag[pos] = s->secretflag[sSTAIRS];
2463
2464
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 323 times.
579 if (redraw)
2465 {
2466 768 auto [x, y] = translate_screen_coordinates_to_world(screen, s->stairx, s->stairy);
2467 768 putcombo(scrollbuf,x,y,s->data[pos],s->cset[pos]);
2468 256 }
2469
2470 579 return true;
2471 }
2472
2473 10529 return false;
2474 11108 }
2475
2476 52912 screen_handles_t create_screen_handles_one(mapscr* base_scr)
2477 {
2478 DCHECK(base_scr->is_valid());
2479
2480 52912 screen_handles_t screen_handles{};
2481 52912 screen_handles[0] = {base_scr, base_scr, base_scr->screen, 0};
2482 52912 return screen_handles;
2483 }
2484
2485 58579008 screen_handles_t create_screen_handles(mapscr* base_scr)
2486 {
2487 DCHECK(get_scr(base_scr->screen) == base_scr);
2488 DCHECK(base_scr->is_valid());
2489
2490 58579008 int screen = base_scr->screen;
2491 screen_handles_t screen_handles;
2492 58579008 screen_handles[0] = {base_scr, base_scr, screen, 0};
2493
2/2
✓ Branch 0 taken 351474048 times.
✓ Branch 1 taken 58579008 times.
410053056 for (int i = 1; i <= 6; i++)
2494 351474048 screen_handles[i] = {base_scr, get_scr_layer_valid(screen, i), screen, i};
2495 58579008 return screen_handles;
2496 }
2497
2498 113471 bool remove_screenstatecombos2(const screen_handles_t& screen_handles, bool do_layers, int32_t what1, int32_t what2)
2499 {
2500 113471 mapscr* scr = screen_handles[0].base_scr;
2501 113471 bool didit=false;
2502
2503
2/2
✓ Branch 0 taken 113471 times.
✓ Branch 1 taken 19970896 times.
20084367 for(int32_t i=0; i<176; i++)
2504 {
2505 19970896 newcombo const& cmb = combobuf[scr->data[i]];
2506
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 19970570 times.
19970896 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2507
4/4
✓ Branch 0 taken 19968994 times.
✓ Branch 1 taken 1576 times.
✓ Branch 2 taken 1134 times.
✓ Branch 3 taken 19967860 times.
19970570 if((cmb.type == what1) || (cmb.type== what2))
2508 {
2509 2710 scr->data[i]++;
2510 2710 didit=true;
2511 2710 }
2512 19970570 }
2513
2514
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 113379 times.
113471 if (do_layers)
2515 {
2516
2/2
✓ Branch 0 taken 680274 times.
✓ Branch 1 taken 113379 times.
793653 for(int32_t j=1; j<=6; j++)
2517 {
2518 680274 mapscr* layer_scr = screen_handles[j].scr;
2519
2/2
✓ Branch 0 taken 195881 times.
✓ Branch 1 taken 484393 times.
680274 if (!layer_scr) continue;
2520
2521
2/2
✓ Branch 0 taken 34475056 times.
✓ Branch 1 taken 195881 times.
34670937 for(int32_t i=0; i<176; i++)
2522 {
2523 34475056 newcombo const& cmb = combobuf[layer_scr->data[i]];
2524
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34475056 times.
34475056 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2525
4/4
✓ Branch 0 taken 34474741 times.
✓ Branch 1 taken 315 times.
✓ Branch 2 taken 319 times.
✓ Branch 3 taken 34474422 times.
34475056 if((cmb.type== what1) || (cmb.type== what2))
2526 {
2527 634 layer_scr->data[i]++;
2528 634 didit=true;
2529 634 }
2530 34475056 }
2531 195881 }
2532 113379 }
2533
2534 // 'do_layers' also means that this is called on an active temp screen, so update its ffcs.
2535
3/4
✓ Branch 0 taken 27675 times.
✓ Branch 1 taken 85796 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 27675 times.
113471 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && do_layers)
2536 {
2537 27675 word c = scr->numFFC();
2538
2/2
✓ Branch 0 taken 80883 times.
✓ Branch 1 taken 27675 times.
108558 for(word i=0; i<c; i++)
2539 {
2540 80883 ffcdata* ffc = &scr->ffcs[i];
2541 80883 newcombo const& cmb = combobuf[ffc->data];
2542
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 80883 times.
80883 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2543
2/4
✓ Branch 0 taken 80883 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 80883 times.
80883 if((cmb.type== what1) || (cmb.type== what2))
2544 {
2545 zc_ffc_modify(*ffc, 1);
2546 didit=true;
2547 }
2548 80883 }
2549 27675 }
2550
2551 113471 return didit;
2552 }
2553
2554 14 bool remove_xstatecombos(const screen_handles_t& screen_handles, byte xflag, bool triggers)
2555 {
2556 14 int screen = screen_handles[0].screen;
2557
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2558 14 return remove_xstatecombos_mi(screen_handles, mi, xflag, triggers);
2559 }
2560 488423566 bool remove_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, byte xflag, bool triggers)
2561 {
2562 488423566 bool didit=false;
2563
2/2
✓ Branch 0 taken 488382605 times.
✓ Branch 1 taken 40961 times.
488423566 if(!getxmapflag_mi(mi, 1<<xflag)) return false;
2564
2565 40961 mapscr* s = screen_handles[0].base_scr;
2566 40961 int screen = s->screen;
2567 40961 bool is_active_screen = is_in_current_region(s);
2568
2569 34122305 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2570
4/4
✓ Branch 0 taken 49456 times.
✓ Branch 1 taken 34031888 times.
✓ Branch 2 taken 1891 times.
✓ Branch 3 taken 34079453 times.
34081344 if(triggers && force_ex_trigger_any(rpos_handle, xflag))
2571 1891 didit = true;
2572
2/2
✓ Branch 0 taken 64673 times.
✓ Branch 1 taken 34014780 times.
34079453 else switch (rpos_handle.ctype())
2573 {
2574 case cLOCKBLOCK: case cLOCKBLOCK2:
2575 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2576 case cCHEST: case cCHEST2:
2577 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2578 case cBOSSCHEST: case cBOSSCHEST2:
2579 {
2580 64673 auto& cmb = rpos_handle.combo();
2581
2/2
✓ Branch 0 taken 62059 times.
✓ Branch 1 taken 2614 times.
64673 if(!(cmb.usrflags&cflag16)) return; //custom state instead of normal state
2582
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 62030 times.
62059 if(cmb.c_attributes[13].getTrunc() == xflag)
2583 {
2584 29 rpos_handle.increment_data();
2585 29 didit=true;
2586 29 }
2587 62059 break;
2588 }
2589 }
2590 34081344 });
2591
2592
4/4
✓ Branch 0 taken 40889 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 31269 times.
✓ Branch 3 taken 9620 times.
40961 if (is_active_screen && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2593 {
2594 31269 word c = s->numFFC();
2595 31269 int screen_index_offset = get_region_screen_offset(screen);
2596
2/2
✓ Branch 0 taken 65746 times.
✓ Branch 1 taken 31269 times.
97015 for (uint8_t i = 0; i < c; i++)
2597 {
2598 65746 auto ffc_handle = *s->getFFCHandle(i, screen_index_offset);
2599 65746 auto& cmb = ffc_handle.combo();
2600
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 65746 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 65730 times.
65746 if(triggers && force_ex_trigger_any(ffc_handle, xflag))
2601 16 didit = true;
2602
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65730 times.
65730 else switch(cmb.type)
2603 {
2604 case cLOCKBLOCK: case cLOCKBLOCK2:
2605 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2606 case cCHEST: case cCHEST2:
2607 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2608 case cBOSSCHEST: case cBOSSCHEST2:
2609 {
2610 if(!(cmb.usrflags&cflag16)) continue; //custom state instead of normal state
2611 if(cmb.c_attributes[13].getTrunc() == xflag)
2612 {
2613 zc_ffc_modify(*ffc_handle.ffc, 1);
2614 didit=true;
2615 }
2616 break;
2617 }
2618 }
2619 65746 }
2620 31269 }
2621
2622 40961 return didit;
2623 488423566 }
2624
2625 15210101 void clear_xstatecombos(const screen_handles_t& screen_handles, bool triggers)
2626 {
2627 15210101 int screen = screen_handles[0].screen;
2628
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14822268 times.
15210101 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2629 15210101 clear_xstatecombos_mi(screen_handles, mi, triggers);
2630 15210101 }
2631
2632 15263236 void clear_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2633 {
2634
2/2
✓ Branch 0 taken 488423552 times.
✓ Branch 1 taken 15263236 times.
503686788 for (int q = 0; q < 32; ++q)
2635 {
2636 488423552 remove_xstatecombos_mi(screen_handles, mi, q, triggers);
2637 488423552 }
2638 15263236 }
2639
2640 bool remove_xdoors(const screen_handles_t& screen_handles, uint dir, uint ind, bool triggers)
2641 {
2642 int screen = screen_handles[0].screen;
2643 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2644 return remove_xdoors_mi(screen_handles, mi, dir, ind, triggers);
2645 }
2646 488423552 bool remove_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, uint dir, uint ind, bool triggers)
2647 {
2648 488423552 bool didit=false;
2649
2/2
✓ Branch 0 taken 488422239 times.
✓ Branch 1 taken 1313 times.
488423552 if (!getxdoor_mi(mi, dir, ind)) return false;
2650
2651 1313 mapscr* scr = screen_handles[0].base_scr;
2652 1313 int screen = scr->screen;
2653 1313 bool is_active_screen = is_in_current_region(scr);
2654
2655 925665 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2656
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 924352 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 924341 times.
924352 if (triggers && force_ex_door_trigger_any(rpos_handle, dir, ind))
2657 11 didit = true;
2658 else; //future door combo types?
2659 924352 });
2660
2661
2/4
✓ Branch 0 taken 1313 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1313 times.
✗ Branch 3 not taken.
1313 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && is_active_screen)
2662 {
2663 1313 word c = scr->numFFC();
2664 1313 int screen_index_offset = get_region_screen_offset(screen);
2665
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1313 times.
1313 for (uint8_t i = 0; i < c; i++)
2666 {
2667 auto ffc_handle = *scr->getFFCHandle(i, screen_index_offset);
2668 if (triggers && force_ex_door_trigger_any(ffc_handle, dir, ind))
2669 didit = true;
2670 else; //future door combo types?
2671 }
2672 1313 }
2673
2674 1313 return didit;
2675 488423552 }
2676
2677 15210101 void clear_xdoors(const screen_handles_t& screen_handles, bool triggers)
2678 {
2679 15210101 int screen = screen_handles[0].screen;
2680
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14822268 times.
15210101 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2681 15210101 return clear_xdoors_mi(screen_handles, mi, triggers);
2682 }
2683
2684 15263236 void clear_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2685 {
2686
2/2
✓ Branch 0 taken 61052944 times.
✓ Branch 1 taken 15263236 times.
76316180 for (int dir = 0; dir < 4; ++dir)
2687
2/2
✓ Branch 0 taken 488423552 times.
✓ Branch 1 taken 61052944 times.
549476496 for (int q = 0; q < 8; ++q)
2688 549476496 remove_xdoors_mi(screen_handles, mi, dir, q, triggers);
2689 15263236 }
2690
2691 885 bool remove_lockblocks(const screen_handles_t& screen_handles)
2692 {
2693 885 return remove_screenstatecombos2(screen_handles, true, cLOCKBLOCK, cLOCKBLOCK2);
2694 }
2695
2696 139 bool remove_bosslockblocks(const screen_handles_t& screen_handles)
2697 {
2698 139 return remove_screenstatecombos2(screen_handles, true, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
2699 }
2700
2701 83659 bool remove_chests(const screen_handles_t& screen_handles)
2702 {
2703 83659 return remove_screenstatecombos2(screen_handles, true, cCHEST, cCHEST2);
2704 }
2705
2706 2484 bool remove_lockedchests(const screen_handles_t& screen_handles)
2707 {
2708 2484 return remove_screenstatecombos2(screen_handles, true, cLOCKEDCHEST, cLOCKEDCHEST2);
2709 }
2710
2711 26212 bool remove_bosschests(const screen_handles_t& screen_handles)
2712 {
2713 26212 return remove_screenstatecombos2(screen_handles, true, cBOSSCHEST, cBOSSCHEST2);
2714 }
2715
2716 1418795 void delete_fireball_shooter(const rpos_handle_t& rpos_handle)
2717 {
2718 1418795 int32_t ct=rpos_handle.ctype();
2719
2720
6/6
✓ Branch 0 taken 1418175 times.
✓ Branch 1 taken 620 times.
✓ Branch 2 taken 1417923 times.
✓ Branch 3 taken 252 times.
✓ Branch 4 taken 1417815 times.
✓ Branch 5 taken 108 times.
1418795 if(ct!=cL_STATUE && ct!=cR_STATUE && ct!=cC_STATUE)
2721 1417815 return;
2722
2723 2465 auto [cx, cy] = rpos_handle.xy();
2724
3/4
✓ Branch 0 taken 252 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 620 times.
✓ Branch 3 taken 108 times.
980 switch(ct)
2725 {
2726 case cL_STATUE:
2727 620 cx += 4;
2728 620 cy += 7;
2729 620 break;
2730
2731 case cR_STATUE:
2732 252 cx -= 8;
2733 252 cy -= 1;
2734 252 break;
2735
2736 case cC_STATUE:
2737 108 break;
2738 }
2739
2740
2/2
✓ Branch 0 taken 980 times.
✓ Branch 1 taken 1485 times.
2465 for(int32_t j=0; j<guys.Count(); j++)
2741 {
2742 // Finds the smallest enemy ID
2743
9/10
✓ Branch 0 taken 399 times.
✓ Branch 1 taken 1086 times.
✓ Branch 2 taken 399 times.
✓ Branch 3 taken 1086 times.
✓ Branch 4 taken 346 times.
✓ Branch 5 taken 53 times.
✓ Branch 6 taken 346 times.
✓ Branch 7 taken 53 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 346 times.
2970 if((int32_t(guys.spr(j)->x)==cx)&&(int32_t(guys.spr(j)->y)==cy)&&(guysbuf[(guys.spr(j)->id)&0xFFF].flags & guy_fire))
2744 {
2745 346 guys.del(j);
2746 346 }
2747 1485 }
2748 1418795 }
2749
2750 45 static int32_t findtrigger(int32_t screen)
2751 {
2752 45 int32_t checkflag=0;
2753 45 int32_t ret = 0;
2754
2755 mapscr* screens[7];
2756
2/2
✓ Branch 0 taken 315 times.
✓ Branch 1 taken 45 times.
360 for (int32_t j = 0; j <= 6; j++)
2757 {
2758 315 screens[j] = get_scr_layer_valid(screen, j);
2759 315 }
2760
2761 45 bool sflag = false;
2762
2/2
✓ Branch 0 taken 7920 times.
✓ Branch 1 taken 45 times.
7965 for(word j=0; j<176; j++)
2763 {
2764
2/2
✓ Branch 0 taken 87648 times.
✓ Branch 1 taken 7920 times.
95568 for(int32_t layer = -1; layer < 6; ++layer)
2765 {
2766 87648 mapscr* scr = screens[layer+1];
2767
2/2
✓ Branch 0 taken 64416 times.
✓ Branch 1 taken 23232 times.
87648 if (!scr) continue;
2768
2769
2/2
✓ Branch 0 taken 32208 times.
✓ Branch 1 taken 32208 times.
64416 if(sflag)
2770 32208 checkflag = scr->sflag[j];
2771 else
2772 32208 checkflag = combobuf[scr->data[j]].flag;
2773 64416 sflag = !sflag;
2774
2/2
✓ Branch 0 taken 32208 times.
✓ Branch 1 taken 32208 times.
64416 if (sflag) --layer;
2775
2776
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 64374 times.
64416 switch(checkflag)
2777 {
2778 case mfANYFIRE:
2779 case mfSTRONGFIRE:
2780 case mfMAGICFIRE:
2781 case mfDIVINEFIRE:
2782 case mfARROW:
2783 case mfSARROW:
2784 case mfGARROW:
2785 case mfSBOMB:
2786 case mfBOMB:
2787 case mfBRANG:
2788 case mfMBRANG:
2789 case mfFBRANG:
2790 case mfWANDMAGIC:
2791 case mfREFMAGIC:
2792 case mfREFFIREBALL:
2793 case mfSWORD:
2794 case mfWSWORD:
2795 case mfMSWORD:
2796 case mfXSWORD:
2797 case mfSWORDBEAM:
2798 case mfWSWORDBEAM:
2799 case mfMSWORDBEAM:
2800 case mfXSWORDBEAM:
2801 case mfHOOKSHOT:
2802 case mfWAND:
2803 case mfHAMMER:
2804 case mfSTRIKE:
2805 42 ret += 1;
2806 42 break;
2807 }
2808 64416 }
2809 7920 }
2810
2811 45 return ret;
2812 }
2813
2814 12340 static void log_trigger_secret_reason(TriggerSource source)
2815 {
2816
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 11888 times.
12340 if (source == TriggerSource::Singular)
2817 {
2818 452 Z_eventlog("Restricted Screen Secrets triggered\n");
2819 452 }
2820 else
2821 {
2822 11888 const char* source_str = "";
2823
7/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 7297 times.
✓ Branch 3 taken 897 times.
✓ Branch 4 taken 3114 times.
✓ Branch 5 taken 500 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 75 times.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
11888 switch (source)
2824 {
2825 case TriggerSource::Singular: break;
2826 7297 case TriggerSource::Unspecified: source_str = "unspecified means"; break;
2827 897 case TriggerSource::EnemiesScreenFlag: source_str = "the 'Enemies->Secret' screen flag"; break;
2828 3114 case TriggerSource::SecretsScreenState: source_str = "the 'Secrets' screen state"; break;
2829 500 case TriggerSource::Script: source_str = "a script"; break;
2830 1 case TriggerSource::ItemsSecret: source_str = "Items->Secrets"; break;
2831 75 case TriggerSource::GenericCombo: source_str = "Generic Combo"; break;
2832 4 case TriggerSource::LightTrigger: source_str = "Light Triggers"; break;
2833 case TriggerSource::SCC: source_str = "SCC"; break;
2834 case TriggerSource::CheatTemp: source_str = "Cheat (Temp)"; break;
2835 case TriggerSource::CheatPerm: source_str = "Cheat (Perm)"; break;
2836 }
2837 11888 Z_eventlog("Screen Secrets triggered by %s\n", source_str);
2838 }
2839 12340 }
2840
2841 // single:
2842 // >-1 : the singular triggering combo
2843 // -1: triggered by some other cause
2844 12132 void trigger_secrets_for_screen(TriggerSource source, mapscr* scr, bool high16only, int32_t single)
2845 {
2846 12132 log_trigger_secret_reason(source);
2847
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 11680 times.
12132 if (single < 0)
2848 11680 get_screen_state(scr->screen).triggered_secrets = true;
2849
2850 12132 bool do_replay_comment = true;
2851 12132 bool from_active_screen = true;
2852 12132 trigger_secrets_for_screen_internal(create_screen_handles(scr), from_active_screen, high16only, single, do_replay_comment);
2853
2854 // Respect secret state carryovers for active screens.
2855
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 11680 times.
12132 if (single >= 0) return;
2856
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 11655 times.
11680 if(scr->nocarry&mSECRET) return;
2857 11655 int cmap = scr->map;
2858 11655 int cscr = scr->screen;
2859 11655 int nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
2860 11655 int nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
2861
2862 11655 std::vector<int32_t> done;
2863
2/2
✓ Branch 0 taken 11450 times.
✓ Branch 1 taken 205 times.
11655 bool looped = (nmap==cmap+1 && nscr==cscr);
2864
2865
6/6
✓ Branch 0 taken 586 times.
✓ Branch 1 taken 11569 times.
✓ Branch 2 taken 86 times.
✓ Branch 3 taken 500 times.
✓ Branch 4 taken 500 times.
✓ Branch 5 taken 11655 times.
12155 while((nmap!=0) && !looped && !(nscr>=128))
2866 {
2867
7/8
✓ Branch 0 taken 388 times.
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 93 times.
✓ Branch 3 taken 295 times.
✓ Branch 4 taken 93 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 89 times.
500 if (nmap - 1 == cur_map && is_in_current_region(nscr) && !get_screen_state(nscr).triggered_secrets)
2868 {
2869
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
2870
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 trigger_secrets_for_screen_internal(create_screen_handles(get_scr(nscr)), from_active_screen, high16only, single, do_replay_comment);
2871
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 get_screen_state(nscr).triggered_secrets = true;
2872 4 }
2873
2874 500 cmap=nmap;
2875 500 cscr=nscr;
2876 500 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
2877 500 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
2878
2879
2/2
✓ Branch 0 taken 443 times.
✓ Branch 1 taken 500 times.
943 for(auto it = done.begin(); it != done.end(); it++)
2880 {
2881
2/2
✓ Branch 0 taken 357 times.
✓ Branch 1 taken 86 times.
443 if(*it == ((nmap-1)<<7)+nscr)
2882 86 looped = true;
2883 443 }
2884
2885
1/2
✓ Branch 0 taken 500 times.
✗ Branch 1 not taken.
500 done.push_back(((nmap-1)<<7)+nscr);
2886 }
2887 12132 }
2888
2889 2550 void trigger_secrets_for_screen(TriggerSource source, int32_t screen, bool high16only, int32_t single)
2890 {
2891 2550 trigger_secrets_for_screen(source, get_scr(screen), high16only, single);
2892 2550 }
2893
2894 19223 void trigger_secrets_for_screen_internal(const screen_handles_t& screen_handles, bool from_active_screen, bool high16only, int32_t single, bool do_replay_comment)
2895 {
2896 19223 mapscr* scr = screen_handles[0].base_scr;
2897 19223 int screen = scr->screen;
2898
2899 // TODO(replays): No real reason for "do_replay_comment" to exist - I just did not want to update many replays when fixing
2900 // slopes in sideview mode (which required loading nearby screens in loadscr).
2901 // TODO(replays): This should just use `screen`.
2902
3/4
✓ Branch 0 taken 19223 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 539 times.
✓ Branch 3 taken 18684 times.
19223 if (replay_is_active() && do_replay_comment)
2903
4/6
✓ Branch 0 taken 12136 times.
✓ Branch 1 taken 6548 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12136 times.
✓ Branch 4 taken 18684 times.
✗ Branch 5 not taken.
18684 replay_step_comment(fmt::format("trigger secrets scr={}", from_active_screen && scr != special_warp_return_scr ? screen : cur_screen));
2904
2905
2/2
✓ Branch 0 taken 7087 times.
✓ Branch 1 taken 12136 times.
19223 if (from_active_screen)
2906 {
2907 6100878 for_every_combo_in_screen(screen_handles, [&](const auto& handle) {
2908
2/4
✓ Branch 0 taken 6086080 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2662 times.
✗ Branch 3 not taken.
6408660 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
2909 319918 return trig.trigger_flags.get(TRIGFLAG_SECRETSTR);
2910 }, ctrigSECRETS);
2911 6088742 });
2912 12136 }
2913
2914 19223 int32_t ft=0; //Flag trigger?
2915 19223 int32_t msflag=0; // Misc. secret flag
2916
2917
2/2
✓ Branch 0 taken 3383248 times.
✓ Branch 1 taken 19223 times.
3402471 for(int32_t i=0; i<176; i++) //Do the 'trigger flags' (non 16-31)
2918 {
2919
4/4
✓ Branch 0 taken 79552 times.
✓ Branch 1 taken 3303696 times.
✓ Branch 2 taken 452 times.
✓ Branch 3 taken 79100 times.
3383248 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2920
2921 // Remember the misc. secret flag; if triggered, use this instead
2922
4/4
✓ Branch 0 taken 153551 times.
✓ Branch 1 taken 3150597 times.
✓ Branch 2 taken 87558 times.
✓ Branch 3 taken 65993 times.
3304148 if(scr->sflag[i]>=mfSECRETS01 && scr->sflag[i]<=mfSECRETS16)
2923 65993 msflag=sSECRET01+(scr->sflag[i]-mfSECRETS01);
2924
4/4
✓ Branch 0 taken 47862 times.
✓ Branch 1 taken 3190293 times.
✓ Branch 2 taken 47336 times.
✓ Branch 3 taken 526 times.
3238155 else if(combobuf[scr->data[i]].flag>=mfSECRETS01 && combobuf[scr->data[i]].flag<=mfSECRETS16)
2925 526 msflag=sSECRET01+(combobuf[scr->data[i]].flag-mfSECRETS01);
2926 else
2927 3237629 msflag=0;
2928
2929
4/4
✓ Branch 0 taken 922853 times.
✓ Branch 1 taken 2381295 times.
✓ Branch 2 taken 85 times.
✓ Branch 3 taken 922768 times.
3304148 if(!high16only || single>=0)
2930 {
2931 2381380 int32_t newflag = -1;
2932
2933
2/2
✓ Branch 0 taken 4762760 times.
✓ Branch 1 taken 2381380 times.
7144140 for(int32_t iter=0; iter<2; ++iter)
2934 {
2935 4762760 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
2936
2937
2/2
✓ Branch 0 taken 2381380 times.
✓ Branch 1 taken 2381380 times.
4762760 if(iter==1) checkflag=scr->sflag[i]; //Placed
2938
2939 4762760 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2940
2/2
✓ Branch 0 taken 4750287 times.
✓ Branch 1 taken 12473 times.
4762760 if (ft != -1) //Change the combos for the secret
2941 {
2942 // Use misc. secret flag instead if one is present
2943
2/2
✓ Branch 0 taken 12441 times.
✓ Branch 1 taken 32 times.
12473 if(msflag!=0)
2944 32 ft=msflag;
2945
2946 12473 rpos_handle_t rpos_handle;
2947
2/2
✓ Branch 0 taken 6541 times.
✓ Branch 1 taken 5932 times.
12473 if (from_active_screen)
2948 {
2949 5932 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
2950 5932 screen_combo_modify_preroutine(rpos_handle);
2951 5932 }
2952
2953
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12473 times.
12473 if(ft==sSECNEXT)
2954 {
2955 scr->data[i]++;
2956 }
2957 else
2958 {
2959 12473 scr->data[i] = scr->secretcombo[ft];
2960 12473 scr->cset[i] = scr->secretcset[ft];
2961 }
2962 12473 newflag = scr->secretflag[ft];
2963
2964
2/2
✓ Branch 0 taken 6541 times.
✓ Branch 1 taken 5932 times.
12473 if (from_active_screen)
2965 5932 screen_combo_modify_postroutine(rpos_handle);
2966 12473 }
2967 4762760 }
2968
2969
2/2
✓ Branch 0 taken 2368913 times.
✓ Branch 1 taken 12467 times.
2381380 if(newflag >-1) scr->sflag[i] = newflag; //Tiered secret
2970
2971
2/2
✓ Branch 0 taken 14288280 times.
✓ Branch 1 taken 2381380 times.
16669660 for(int32_t j=1; j<=6; j++) //Layers
2972 {
2973 14288280 mapscr* layer_scr = screen_handles[j].scr;
2974
2/2
✓ Branch 0 taken 4300978 times.
✓ Branch 1 taken 9987302 times.
14288280 if (!layer_scr) continue;
2975
2976
3/4
✓ Branch 0 taken 770 times.
✓ Branch 1 taken 4300208 times.
✓ Branch 2 taken 770 times.
✗ Branch 3 not taken.
4300978 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2977
2978 4300978 int32_t newflag2 = -1;
2979
2980 // Remember the misc. secret flag; if triggered, use this instead
2981
4/4
✓ Branch 0 taken 18068 times.
✓ Branch 1 taken 4282910 times.
✓ Branch 2 taken 6284 times.
✓ Branch 3 taken 11784 times.
4300978 if(layer_scr->sflag[i]>=mfSECRETS01 && layer_scr->sflag[i]<=mfSECRETS16)
2982 11784 msflag=sSECRET01+(layer_scr->sflag[i]-mfSECRETS01);
2983
4/4
✓ Branch 0 taken 132026 times.
✓ Branch 1 taken 4157168 times.
✓ Branch 2 taken 130774 times.
✓ Branch 3 taken 1252 times.
4289194 else if(combobuf[layer_scr->data[i]].flag>=mfSECRETS01 && combobuf[layer_scr->data[i]].flag<=mfSECRETS16)
2984 1252 msflag=sSECRET01+(combobuf[layer_scr->data[i]].flag-mfSECRETS01);
2985 else
2986 4287942 msflag=0;
2987
2988
2/2
✓ Branch 0 taken 8601956 times.
✓ Branch 1 taken 4300978 times.
12902934 for(int32_t iter=0; iter<2; ++iter)
2989 {
2990 8601956 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
2991
2/2
✓ Branch 0 taken 4300978 times.
✓ Branch 1 taken 4300978 times.
8601956 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
2992
2993 8601956 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2994
2/2
✓ Branch 0 taken 8600177 times.
✓ Branch 1 taken 1779 times.
8601956 if (ft != -1) //Change the combos for the secret
2995 {
2996 // Use misc. secret flag instead if one is present
2997
2/2
✓ Branch 0 taken 1777 times.
✓ Branch 1 taken 2 times.
1779 if(msflag!=0)
2998 2 ft=msflag;
2999
3000
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1779 times.
1779 if(ft==sSECNEXT)
3001 {
3002 layer_scr->data[i]++;
3003 }
3004 else
3005 {
3006 1779 layer_scr->data[i] = layer_scr->secretcombo[ft];
3007 1779 layer_scr->cset[i] = layer_scr->secretcset[ft];
3008 }
3009 1779 newflag2 = layer_scr->secretflag[ft];
3010 1779 int32_t c=layer_scr->data[i];
3011 1779 int32_t cs=layer_scr->cset[i];
3012
3013
3/4
✓ Branch 0 taken 908 times.
✓ Branch 1 taken 871 times.
✓ Branch 2 taken 908 times.
✗ Branch 3 not taken.
1779 if (from_active_screen && combobuf[c].type==cSPINTILE1) //Surely this means we can have spin tiles on layers 3+? Isn't that bad? ~Joe123
3014 {
3015 auto [offx, offy] = translate_screen_coordinates_to_world(screen, COMBOX(i), COMBOY(i));
3016 addenemy(screen,offx,offy,(cs<<12)+eSPINTILE1,combobuf[c].o_tile+zc_max(1,combobuf[c].frames));
3017 }
3018 1779 }
3019 8601956 }
3020
3021
2/2
✓ Branch 0 taken 1766 times.
✓ Branch 1 taken 4299212 times.
4300978 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered secret
3022 4300978 }
3023 2381380 }
3024 3304148 }
3025
3026 19223 word c = scr->numFFC();
3027
2/2
✓ Branch 0 taken 508334 times.
✓ Branch 1 taken 19223 times.
527557 for(word i=0; i<c; i++) //FFC 'trigger flags'
3028 {
3029
3/4
✓ Branch 0 taken 494280 times.
✓ Branch 1 taken 14054 times.
✓ Branch 2 taken 14054 times.
✗ Branch 3 not taken.
508334 if(single>=0) if(i+176!=single) continue;
3030
3031
3/4
✓ Branch 0 taken 166649 times.
✓ Branch 1 taken 327631 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 166649 times.
494280 if((!high16only)||(single>=0))
3032 {
3033 //for (int32_t iter=0; iter<1; ++iter) // Only one kind of FFC flag now.
3034 {
3035 327631 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3036 //No placed flags yet
3037
3038 327631 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
3039
2/2
✓ Branch 0 taken 327600 times.
✓ Branch 1 taken 31 times.
327631 if (ft != -1) //Change the ffc's combo
3040 {
3041
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if(ft==sSECNEXT)
3042 {
3043 zc_ffc_modify(scr->ffcs[i], 1);
3044 }
3045 else
3046 {
3047 31 zc_ffc_set(scr->ffcs[i], scr->secretcombo[ft]);
3048 31 scr->ffcs[i].cset = scr->secretcset[ft];
3049 }
3050 31 }
3051 }
3052 327631 }
3053 494280 }
3054
3055
2/2
✓ Branch 0 taken 16725 times.
✓ Branch 1 taken 2498 times.
19223 if(checktrigger) //Hit all triggers->16-31
3056 {
3057 2498 checktrigger=false;
3058
3059
2/2
✓ Branch 0 taken 2474 times.
✓ Branch 1 taken 24 times.
2498 if(scr->flags6&fTRIGGERF1631)
3060 {
3061 24 int32_t tr = findtrigger(screen); //Normal flags
3062
3063
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 10 times.
24 if(tr)
3064 {
3065 14 Z_eventlog("Hit All Triggers->16-31 not fulfilled (%d trigger flag%s remain).\n", tr, tr>1?"s":"");
3066 14 goto endhe;
3067 }
3068 10 }
3069 2484 }
3070
3071
2/2
✓ Branch 0 taken 3380784 times.
✓ Branch 1 taken 19209 times.
3399993 for(int32_t i=0; i<176; i++) // Do the 16-31 secrets
3072 {
3073 //If it's an enemies->secret screen, only do the high 16 if told to
3074 //That way you can have secret and burn/bomb entrance separately
3075 3380784 bool old_enem_secret = get_qr(qr_ENEMIES_SECRET_ONLY_16_31);
3076
6/6
✓ Branch 0 taken 2780624 times.
✓ Branch 1 taken 600160 times.
✓ Branch 2 taken 85184 times.
✓ Branch 3 taken 3295600 times.
✓ Branch 4 taken 19536 times.
✓ Branch 5 taken 65648 times.
3380784 if(((!(old_enem_secret && (scr->flags2&fCLEARSECRET)) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM))
3077 {
3078 3315136 int32_t newflag = -1;
3079
3080
2/2
✓ Branch 0 taken 6630272 times.
✓ Branch 1 taken 3315136 times.
9945408 for(int32_t iter=0; iter<2; ++iter)
3081 {
3082 6630272 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
3083
3084
2/2
✓ Branch 0 taken 3315136 times.
✓ Branch 1 taken 3315136 times.
6630272 if(iter==1) checkflag=scr->sflag[i]; //Placed
3085
3086
4/4
✓ Branch 0 taken 200805 times.
✓ Branch 1 taken 6429467 times.
✓ Branch 2 taken 133230 times.
✓ Branch 3 taken 67575 times.
6630272 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3087 {
3088 67575 rpos_handle_t rpos_handle;
3089
2/2
✓ Branch 0 taken 10367 times.
✓ Branch 1 taken 57208 times.
67575 if (from_active_screen)
3090 {
3091 57208 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
3092 57208 screen_combo_modify_preroutine(rpos_handle);
3093 57208 }
3094
3095 67575 scr->data[i] = scr->secretcombo[checkflag-16+4];
3096 67575 scr->cset[i] = scr->secretcset[checkflag-16+4];
3097 67575 newflag = scr->secretflag[checkflag-16+4];
3098
3099
2/2
✓ Branch 0 taken 10367 times.
✓ Branch 1 taken 57208 times.
67575 if (from_active_screen)
3100 57208 screen_combo_modify_postroutine(rpos_handle);
3101 67575 }
3102 6630272 }
3103
3104
2/2
✓ Branch 0 taken 3247589 times.
✓ Branch 1 taken 67547 times.
3315136 if(newflag >-1) scr->sflag[i] = newflag; //Tiered flag
3105
3106
2/2
✓ Branch 0 taken 19890816 times.
✓ Branch 1 taken 3315136 times.
23205952 for(int32_t j=1; j<=6; j++) //Layers
3107 {
3108 19890816 mapscr* layer_scr = screen_handles[j].scr;
3109
2/2
✓ Branch 0 taken 5992096 times.
✓ Branch 1 taken 13898720 times.
19890816 if (!layer_scr) continue;
3110
3111 5992096 int32_t newflag2 = -1;
3112
3113
2/2
✓ Branch 0 taken 11984192 times.
✓ Branch 1 taken 5992096 times.
17976288 for(int32_t iter=0; iter<2; ++iter)
3114 {
3115 11984192 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
3116
3117
2/2
✓ Branch 0 taken 5992096 times.
✓ Branch 1 taken 5992096 times.
11984192 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
3118
3119
4/4
✓ Branch 0 taken 159433 times.
✓ Branch 1 taken 11824759 times.
✓ Branch 2 taken 136546 times.
✓ Branch 3 taken 22887 times.
11984192 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3120 {
3121 22887 layer_scr->data[i] = layer_scr->secretcombo[checkflag-16+4];
3122 22887 layer_scr->cset[i] = layer_scr->secretcset[checkflag-16+4];
3123 22887 newflag2 = layer_scr->secretflag[checkflag-16+4];
3124 22887 }
3125 11984192 }
3126
3127
2/2
✓ Branch 0 taken 5969209 times.
✓ Branch 1 taken 22887 times.
5992096 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered flag
3128 5992096 }
3129 3315136 }
3130 3380784 }
3131
3132
2/2
✓ Branch 0 taken 508074 times.
✓ Branch 1 taken 19209 times.
527283 for(word i=0; i<c; i++) // FFCs
3133 {
3134
6/6
✓ Branch 0 taken 468053 times.
✓ Branch 1 taken 40021 times.
✓ Branch 2 taken 15497 times.
✓ Branch 3 taken 492577 times.
✓ Branch 4 taken 3657 times.
✓ Branch 5 taken 11840 times.
508074 if((!(scr->flags2&fCLEARSECRET) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM)
3135 {
3136 496234 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3137
3138 //No placed flags yet
3139
4/4
✓ Branch 0 taken 93 times.
✓ Branch 1 taken 496141 times.
✓ Branch 2 taken 81 times.
✓ Branch 3 taken 12 times.
496234 if((checkflag > 15)&&(checkflag < 32)) //If we find a flag, change the combo
3140 {
3141
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 if (from_active_screen)
3142 9 zc_ffc_set(scr->ffcs[i], scr->secretcombo[checkflag - 16 + 4]);
3143 else
3144 3 scr->ffcs[i].data = scr->secretcombo[checkflag - 16 + 4];
3145 12 scr->ffcs[i].cset = scr->secretcset[checkflag-16+4];
3146 12 }
3147 496234 }
3148 527283 }
3149
3150 endhe:
3151
3152
1/2
✓ Branch 0 taken 19223 times.
✗ Branch 1 not taken.
19223 if (scr->flags4&fDISABLETIME) //Finish timed warp if 'Secrets Disable Timed Warp'
3153 {
3154 if (from_active_screen)
3155 activated_timed_warp = true;
3156 scr->timedwarptics = 0;
3157 }
3158 19223 }
3159
3160 // x,y are world coordinates.
3161 // Returns true if there is a flag (either combo, screen, or ffc) at (x, y).
3162 // Out parameters will be set if the flag is Trigger->Self, which modifies how secrets will be triggered.
3163 13982906 static bool has_flag_trigger(int32_t x, int32_t y, int32_t flag, rpos_t& out_rpos, bool& out_single16)
3164 {
3165
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13982906 times.
13982906 if (!is_in_world_bounds(x, y)) return false;
3166
3167 13982906 bool found_cflag = false;
3168 13982906 bool found_nflag = false;
3169 13982906 bool single16 = false;
3170 13982906 rpos_t rpos = rpos_t::None;
3171
3172
2/2
✓ Branch 0 taken 13980804 times.
✓ Branch 1 taken 97868060 times.
111848864 for (int32_t layer = -1; layer < 6; layer++)
3173 {
3174
2/2
✓ Branch 0 taken 97865958 times.
✓ Branch 1 taken 2102 times.
97868060 if (MAPFLAG2(layer, x, y) == flag)
3175 {
3176 2102 found_nflag = true;
3177 2102 break;
3178 }
3179 97865958 }
3180
3181
2/2
✓ Branch 0 taken 13982517 times.
✓ Branch 1 taken 97878647 times.
111861164 for (int32_t layer = -1; layer < 6; layer++)
3182 {
3183
2/2
✓ Branch 0 taken 97878258 times.
✓ Branch 1 taken 389 times.
97878647 if (MAPCOMBOFLAG2(layer, x, y) == flag)
3184 {
3185 389 found_cflag = true;
3186 389 break;
3187 }
3188 97878258 }
3189
3190
2/2
✓ Branch 0 taken 97880342 times.
✓ Branch 1 taken 13982906 times.
111863248 for (int32_t i=-1; i<6; i++) // Look for Trigger->Self on all layers
3191 {
3192
2/2
✓ Branch 0 taken 97865628 times.
✓ Branch 1 taken 14714 times.
97880342 if (found_nflag) // Trigger->Self (a.k.a Singular) is inherent
3193 {
3194
3/4
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 14602 times.
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
14714 if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE) && (MAPFLAG2(i, x, y) == flag))
3195 {
3196 112 rpos = COMBOPOS_REGION(x, y);
3197 112 }
3198
3/4
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 14546 times.
✓ Branch 2 taken 56 times.
✗ Branch 3 not taken.
14602 else if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE16) && (MAPFLAG2(i, x, y) == flag))
3199 {
3200 56 rpos = COMBOPOS_REGION(x, y);
3201 56 single16 = true;
3202 56 }
3203 14714 }
3204
3205
2/2
✓ Branch 0 taken 97877619 times.
✓ Branch 1 taken 2723 times.
97880342 if (found_cflag) // Trigger->Self (a.k.a Singular) is non-inherent
3206 {
3207
3/4
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 2468 times.
✓ Branch 2 taken 255 times.
✗ Branch 3 not taken.
2723 if ((MAPFLAG2(i, x, y) == mfSINGLE) && (MAPCOMBOFLAG2(i, x, y) == flag))
3208 {
3209 255 rpos = COMBOPOS_REGION(x, y);
3210 255 }
3211
3/4
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 2439 times.
✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
2468 else if ((MAPFLAG2(i, x, y) == mfSINGLE16) && (MAPCOMBOFLAG2(i, x, y) == flag))
3212 {
3213 29 rpos = COMBOPOS_REGION(x, y);
3214 29 single16 = true;
3215 29 }
3216 2723 }
3217 97880342 }
3218
3219 13982906 out_rpos = rpos;
3220 13982906 out_single16 = single16;
3221
4/4
✓ Branch 0 taken 13980804 times.
✓ Branch 1 taken 2102 times.
✓ Branch 2 taken 13980419 times.
✓ Branch 3 taken 385 times.
13982906 return found_nflag || found_cflag || MAPFFCOMBOFLAG(x,y) == flag;
3222 13982906 }
3223
3224 4604586 bool trigger_secrets_if_flag(int32_t x, int32_t y, int32_t flag, bool setflag)
3225 {
3226
8/8
✓ Branch 0 taken 4604346 times.
✓ Branch 1 taken 240 times.
✓ Branch 2 taken 4602449 times.
✓ Branch 3 taken 1897 times.
✓ Branch 4 taken 4601929 times.
✓ Branch 5 taken 520 times.
✓ Branch 6 taken 952 times.
✓ Branch 7 taken 4600977 times.
4604586 if (x < -16 || y < -16 || x >= world_w || y >= world_h) return false;
3227
3228 4600977 mapscr* scr = NULL;
3229 4600977 int32_t screen = -1;
3230 4600977 rpos_t trigger_rpos = rpos_t::None;
3231 4600977 bool single16 = false;
3232
3233 4600977 std::vector<std::pair<int, int>> coords;
3234
1/2
✓ Branch 0 taken 4600977 times.
✗ Branch 1 not taken.
4600977 coords.push_back({x, y});
3235
1/2
✓ Branch 0 taken 4600977 times.
✗ Branch 1 not taken.
4600977 coords.push_back({x + 15, y});
3236
1/2
✓ Branch 0 taken 4600977 times.
✗ Branch 1 not taken.
4600977 coords.push_back({x, y + 15});
3237
1/2
✓ Branch 0 taken 4600977 times.
✗ Branch 1 not taken.
4600977 coords.push_back({x + 15, y + 15});
3238 4600977 std::vector<rpos_t> rposes_seen;
3239
2/2
✓ Branch 0 taken 4598479 times.
✓ Branch 1 taken 18398387 times.
87336590 for (auto [x, y] : coords)
3240 {
3241
2/4
✓ Branch 0 taken 18398387 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18398387 times.
✗ Branch 3 not taken.
36796774 rpos_t rpos = COMBOPOS_REGION_B(x, y);
3242
2/2
✓ Branch 0 taken 18184458 times.
✓ Branch 1 taken 213929 times.
18398387 if (rpos == rpos_t::None)
3243 213929 continue;
3244
3245
4/6
✓ Branch 0 taken 18184458 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18184458 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 18184447 times.
36368916 if (MAPFFCOMBOFLAG(x, y) == flag)
3246 {
3247
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
22 screen = get_screen_for_world_xy(x, y);
3248 11 break;
3249 }
3250
3251 18184447 bool seen = false;
3252
2/2
✓ Branch 0 taken 13982906 times.
✓ Branch 1 taken 22894140 times.
36877046 for (rpos_t r : rposes_seen)
3253 {
3254
2/2
✓ Branch 0 taken 18692599 times.
✓ Branch 1 taken 4201541 times.
22894140 if (r == rpos)
3255 {
3256 4201541 seen = true;
3257 4201541 break;
3258 }
3259 }
3260
2/2
✓ Branch 0 taken 13982906 times.
✓ Branch 1 taken 4201541 times.
18184447 if (seen)
3261 4201541 continue;
3262
3263
1/2
✓ Branch 0 taken 13982906 times.
✗ Branch 1 not taken.
13982906 rposes_seen.push_back(rpos);
3264
4/6
✓ Branch 0 taken 13982906 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13982906 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2487 times.
✓ Branch 5 taken 13980419 times.
27965812 if (has_flag_trigger(x, y, flag, trigger_rpos, single16))
3265 {
3266
2/4
✓ Branch 0 taken 2487 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2487 times.
✗ Branch 3 not taken.
4974 screen = get_screen_for_world_xy(x, y);
3267 2487 break;
3268 }
3269 }
3270
3271
3/4
✓ Branch 0 taken 2498 times.
✓ Branch 1 taken 4598479 times.
✓ Branch 2 taken 2498 times.
✗ Branch 3 not taken.
4600977 if (screen != -1) scr = get_scr(screen);
3272
2/2
✓ Branch 0 taken 2498 times.
✓ Branch 1 taken 4598479 times.
4600977 if (!scr) return false;
3273
3274
2/2
✓ Branch 0 taken 2046 times.
✓ Branch 1 taken 452 times.
2498 if (trigger_rpos == rpos_t::None)
3275 {
3276 2046 checktrigger = true;
3277
1/2
✓ Branch 0 taken 2046 times.
✗ Branch 1 not taken.
2046 trigger_secrets_for_screen(TriggerSource::Unspecified, screen);
3278 2046 }
3279 else
3280 {
3281 452 checktrigger = true;
3282
2/4
✓ Branch 0 taken 452 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 452 times.
✗ Branch 3 not taken.
452 trigger_secrets_for_screen(TriggerSource::Singular, scr, single16, RPOS_TO_POS(trigger_rpos));
3283 }
3284
3285
1/2
✓ Branch 0 taken 2498 times.
✗ Branch 1 not taken.
2498 sfx(scr->secretsfx);
3286
3287
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 2477 times.
2498 if(scr->flags6&fTRIGGERFPERM)
3288 {
3289
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 int32_t flags_remaining = findtrigger(screen); //Normal flags
3290
3291
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 9 times.
21 if (flags_remaining)
3292 {
3293
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 Z_eventlog("Hit All Triggers->Perm Secret not fulfilled (%d trigger flag%s remain).\n", flags_remaining, flags_remaining>1?"s":"");
3294 12 setflag=false;
3295 12 }
3296
3297 // Only actually trigger secrets now if 1) all triggers are gone and 2) QR qr_ALLTRIG_PERMSEC_NO_TEMP is off, in
3298 // which case only the screen state for mSECRET may be set below.
3299
4/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 3 times.
21 if (!flags_remaining && !get_qr(qr_ALLTRIG_PERMSEC_NO_TEMP))
3300 {
3301
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 trigger_secrets_for_screen(TriggerSource::Unspecified, scr, scr->flags6&fTRIGGERF1631, -1);
3302 6 }
3303 21 }
3304
3305
5/6
✓ Branch 0 taken 2384 times.
✓ Branch 1 taken 114 times.
✓ Branch 2 taken 2384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1108 times.
✓ Branch 5 taken 1276 times.
2498 if (setflag && canPermSecret(cur_dmap, screen))
3306
2/2
✓ Branch 0 taken 813 times.
✓ Branch 1 taken 463 times.
2089 if(!(scr->flags5&fTEMPSECRETS))
3307
1/2
✓ Branch 0 taken 813 times.
✗ Branch 1 not taken.
813 setmapflag(scr, mSECRET);
3308
3309 2498 return true;
3310 4604586 }
3311
3312 15389922 void update_slopes()
3313 {
3314
2/2
✓ Branch 0 taken 142356 times.
✓ Branch 1 taken 15389922 times.
15532278 for (auto& p : slopes)
3315 {
3316 142356 slope_object& s = p.second;
3317 142356 s.updateslope(); //sets old x/y poses
3318 }
3319 15389922 }
3320
3321 14930115 void update_freeform_combos()
3322 {
3323 14930115 ffscript_engine(false);
3324
2/2
✓ Branch 0 taken 24172 times.
✓ Branch 1 taken 14905943 times.
14930115 if ( !FFCore.system_suspend[susptUPDATEFFC] )
3325 {
3326 14905943 int wrap_right = world_w + 32;
3327 14905943 int wrap_bottom = world_h + 32;
3328
3329 488487635 for_every_ffc([&](const ffc_handle_t& ffc_handle) {
3330 473581692 mapscr* scr = ffc_handle.scr;
3331 473581692 ffcdata& thisffc = *ffc_handle.ffc;
3332
3333 // Combo 0?
3334
2/2
✓ Branch 0 taken 47283515 times.
✓ Branch 1 taken 426298177 times.
473581692 if(thisffc.data==0)
3335 426298177 return;
3336
3337 // Changer?
3338
2/2
✓ Branch 0 taken 562821 times.
✓ Branch 1 taken 46720694 times.
47283515 if(thisffc.flags&ffc_changer)
3339 562821 return;
3340
3341 // Stationary?
3342
2/2
✓ Branch 0 taken 9844 times.
✓ Branch 1 taken 46710850 times.
46720694 if(thisffc.flags&ffc_stationary)
3343 9844 return;
3344
3345 // Frozen because Hero's holding up an item?
3346
3/4
✓ Branch 0 taken 157429 times.
✓ Branch 1 taken 46553421 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 157429 times.
46710850 if(Hero.getHoldClk()>0 && (thisffc.flags&ffc_ignoreholdup)==0)
3347 157429 return;
3348
3349 // Check for changers
3350
2/2
✓ Branch 0 taken 31045342 times.
✓ Branch 1 taken 15508079 times.
46553421 if (thisffc.link==0)
3351 {
3352 446641935 for_some_ffcs([&](const ffc_handle_t& other_ffc_handle) {
3353
2/2
✓ Branch 0 taken 15506442 times.
✓ Branch 1 taken 415627414 times.
431133856 if (ffc_handle.id == other_ffc_handle.id)
3354 15506442 return true;
3355
3356 415627414 ffcdata& otherffc = *other_ffc_handle.ffc;
3357 // Combo 0?
3358
2/2
✓ Branch 0 taken 147056060 times.
✓ Branch 1 taken 268571354 times.
415627414 if(otherffc.data==0)
3359 268571354 return true;
3360
3361 // Not a changer?
3362
2/2
✓ Branch 0 taken 142874031 times.
✓ Branch 1 taken 4182029 times.
147056060 if(!(otherffc.flags&ffc_changer))
3363 142874031 return true;
3364
3365 // Ignore this changer?
3366
4/4
✓ Branch 0 taken 564215 times.
✓ Branch 1 taken 3617814 times.
✓ Branch 2 taken 308097 times.
✓ Branch 3 taken 3309717 times.
4182029 if((otherffc.x.getInt()==thisffc.changer_x&&otherffc.y.getInt()==thisffc.changer_y) || thisffc.flags&ffc_ignorechanger)
3367 872312 return true;
3368
3369
3/4
✓ Branch 0 taken 2870799 times.
✓ Branch 1 taken 438918 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3663 times.
3313380 if((isonline(thisffc.x.getZLong(), thisffc.y.getZLong(), thisffc.prev_changer_x, thisffc.prev_changer_y, otherffc.x.getZLong(), otherffc.y.getZLong()) || // Along the line, or...
3370 ( // At exactly the same position,
3371
2/2
✓ Branch 0 taken 217547 times.
✓ Branch 1 taken 2653252 times.
2870799 (thisffc.x==otherffc.x && thisffc.y==otherffc.y))
3372
2/2
✓ Branch 0 taken 2435705 times.
✓ Branch 1 taken 2653252 times.
217547 ||
3373 //or imprecision and close enough
3374
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
5306504 ( (thisffc.flags&ffc_imprecisionchanger) && ((abs(thisffc.x.getZLong() - otherffc.x.getZLong()) < 10000) && abs(thisffc.y.getZLong() - otherffc.y.getZLong()) < 10000) )
3375 )
3376 && //and...
3377
2/2
✓ Branch 0 taken 3663 times.
✓ Branch 1 taken 2870960 times.
2874623 (thisffc.prev_changer_x>-10000000 && thisffc.prev_changer_y>-10000000)) // This isn't the first frame on this screen
3378 {
3379 3663 zc_ffc_changer(thisffc, otherffc, ffc_handle.id, other_ffc_handle.id);
3380 3663 return false;
3381 }
3382
3383 2870960 return true;
3384 430082568 });
3385 15508079 }
3386
3387
2/2
✓ Branch 0 taken 31045342 times.
✓ Branch 1 taken 15508079 times.
46553421 ffcdata* linked_ffc = thisffc.link ? get_ffc_handle(thisffc.link - 1).ffc : nullptr;
3388
4/4
✓ Branch 0 taken 15508079 times.
✓ Branch 1 taken 31045342 times.
✓ Branch 2 taken 15430786 times.
✓ Branch 3 taken 15614556 times.
46553421 if (linked_ffc ? !linked_ffc->delay : !thisffc.delay)
3389 {
3390
4/4
✓ Branch 0 taken 182609 times.
✓ Branch 1 taken 15431947 times.
✓ Branch 2 taken 85331 times.
✓ Branch 3 taken 97278 times.
15614556 if(thisffc.link && (thisffc.link-1) != ffc_handle.id)
3391 {
3392 97278 thisffc.prev_changer_x = thisffc.x.getZLong();
3393 97278 thisffc.prev_changer_y = thisffc.y.getZLong();
3394 97278 thisffc.x += linked_ffc->vx;
3395 97278 thisffc.y += linked_ffc->vy;
3396 97278 }
3397 else
3398 {
3399 15517278 thisffc.prev_changer_x = thisffc.x.getZLong();
3400 15517278 thisffc.prev_changer_y = thisffc.y.getZLong();
3401 15517278 thisffc.x += thisffc.vx;
3402 15517278 thisffc.y += thisffc.vy;
3403 15517278 thisffc.vx += thisffc.ax;
3404 15517278 thisffc.vy += thisffc.ay;
3405
3406
3407
2/2
✓ Branch 0 taken 1192093 times.
✓ Branch 1 taken 14325185 times.
15517278 if(get_qr(qr_OLD_FFC_SPEED_CAP))
3408 {
3409
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vx>128) thisffc.vx=128;
3410
3411
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vx<-128) thisffc.vx=-128;
3412
3413
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vy>128) thisffc.vy=128;
3414
3415
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vy<-128) thisffc.vy=-128;
3416 14325185 }
3417 }
3418 15614556 }
3419 else
3420 {
3421
3/4
✓ Branch 0 taken 1161 times.
✓ Branch 1 taken 76132 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1161 times.
30938865 if(!thisffc.link || (thisffc.link-1) == ffc_handle.id)
3422 76132 thisffc.delay--;
3423 }
3424
3425 // Check if the FFC's off the side of the screen
3426
3427 // Left
3428
2/2
✓ Branch 0 taken 10449 times.
✓ Branch 1 taken 15681400 times.
15691849 if(thisffc.x<-32)
3429 {
3430
2/2
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 10196 times.
10449 if(scr->flags6&fWRAPAROUNDFF)
3431 {
3432 253 thisffc.x = wrap_right+(thisffc.x+32);
3433 253 thisffc.solid_update(false);
3434 253 thisffc.prev_changer_y = thisffc.y.getZLong();
3435 // Re-enable previous changer
3436 253 thisffc.changer_x = -1000;
3437 253 thisffc.changer_y = -1000;
3438 253 }
3439
2/2
✓ Branch 0 taken 10127 times.
✓ Branch 1 taken 69 times.
10196 else if(thisffc.x<-64)
3440 {
3441 69 zc_ffc_set(thisffc, 0);
3442 69 thisffc.flags&=~ffc_carryover;
3443 69 }
3444 10449 }
3445 // Right
3446
2/2
✓ Branch 0 taken 15681219 times.
✓ Branch 1 taken 181 times.
15681400 else if(thisffc.x>=wrap_right)
3447 {
3448
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 53 times.
181 if(scr->flags6&fWRAPAROUNDFF)
3449 {
3450 128 thisffc.x = thisffc.x-wrap_right-32;
3451 128 thisffc.solid_update(false);
3452 128 thisffc.prev_changer_y = thisffc.y.getZLong();
3453 128 thisffc.changer_x = -1000;
3454 128 thisffc.changer_y = -1000;
3455 128 }
3456 else
3457 {
3458 53 zc_ffc_set(thisffc, 0);
3459 53 thisffc.flags&=~ffc_carryover;
3460 }
3461 181 }
3462
3463 // Top
3464
2/2
✓ Branch 0 taken 25806 times.
✓ Branch 1 taken 15666043 times.
15691849 if(thisffc.y<-32)
3465 {
3466
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 25798 times.
25806 if(scr->flags6&fWRAPAROUNDFF)
3467 {
3468 8 thisffc.y = wrap_bottom+(thisffc.y+32);
3469 8 thisffc.solid_update(false);
3470 8 thisffc.prev_changer_x = thisffc.x.getZLong();
3471 8 thisffc.changer_x = -1000;
3472 8 thisffc.changer_y = -1000;
3473 8 }
3474
2/2
✓ Branch 0 taken 25481 times.
✓ Branch 1 taken 317 times.
25798 else if(thisffc.y<-64)
3475 {
3476 317 zc_ffc_set(thisffc, 0);
3477 317 thisffc.flags&=~ffc_carryover;
3478 317 }
3479 25806 }
3480 // Bottom
3481
2/2
✓ Branch 0 taken 15665175 times.
✓ Branch 1 taken 868 times.
15666043 else if(thisffc.y>=wrap_bottom)
3482 {
3483
2/2
✓ Branch 0 taken 753 times.
✓ Branch 1 taken 115 times.
868 if(scr->flags6&fWRAPAROUNDFF)
3484 {
3485 753 thisffc.y = thisffc.y-wrap_bottom-32;
3486 753 thisffc.solid_update(false);
3487 753 thisffc.prev_changer_y = thisffc.x.getZLong();
3488 753 thisffc.changer_x = -1000;
3489 753 thisffc.changer_y = -1000;
3490 753 }
3491 else
3492 {
3493 115 zc_ffc_set(thisffc, 0);
3494 115 thisffc.flags&=~ffc_carryover;
3495 }
3496 868 }
3497 15691849 thisffc.solid_update();
3498 442720120 });
3499 14905943 }
3500 14930115 }
3501
3502 bool hitflag(int32_t x, int32_t y, int32_t flagtype, byte layers)
3503 {
3504 for(int q = 0; q < 7; ++q)
3505 {
3506 if(layers&(1<<q)) //if layer is to be checked
3507 if(MAPFLAG2(q-1,x,y)==flagtype||MAPCOMBOFLAG2(q-1,x,y)==flagtype) //matching flag
3508 return true;
3509 }
3510 return false;
3511 }
3512
3513 231 optional<int> nextscr(int screen, int dir)
3514 {
3515 231 auto [m, s] = nextscr2(cur_map, screen, dir);
3516
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231 times.
231 if (m == -1) return nullopt;
3517 462 return (m<<7) + s;
3518 231 }
3519
3520 1064 std::pair<int32_t, int32_t> nextscr2(int32_t dir)
3521 {
3522 1064 int32_t map = cur_map;
3523
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1064 times.
1064 int32_t screen = screenscrolling ? scrolling_hero_screen : Hero.current_screen;
3524 1064 return nextscr2(map, screen, dir);
3525 }
3526
3527 5582 std::pair<int32_t, int32_t> nextscr2(int map, int screen, int32_t dir)
3528 {
3529 5582 screen = screen_index_direction(screen, (direction)dir);
3530
3531 // need to check for screens on other maps, 's' not valid, etc.
3532 5582 int32_t index = (hero_scr->sidewarpindex >> (dir*2))&3;
3533
3534 // Fun fact: when a scrolling warp is triggered, this function
3535 // is never even called! - Saf
3536
2/2
✓ Branch 0 taken 3330 times.
✓ Branch 1 taken 2252 times.
6126 if(hero_scr->sidewarptype[index] == 3) // scrolling warp
3537 {
3538
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 482 times.
✓ Branch 2 taken 527 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 697 times.
2252 switch(dir)
3539 {
3540 case up:
3541
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 399 times.
482 if(!(hero_scr->flags2&wfUP)) goto nowarp;
3542
3543 83 break;
3544
3545 case down:
3546
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 448 times.
527 if(!(hero_scr->flags2&wfDOWN)) goto nowarp;
3547
3548 79 break;
3549
3550 case left:
3551
2/2
✓ Branch 0 taken 209 times.
✓ Branch 1 taken 337 times.
546 if(!(hero_scr->flags2&wfLEFT)) goto nowarp;
3552
3553 209 break;
3554
3555 case right:
3556
2/2
✓ Branch 0 taken 173 times.
✓ Branch 1 taken 524 times.
697 if(!(hero_scr->flags2&wfRIGHT)) goto nowarp;
3557
3558 173 break;
3559 }
3560
3561 544 map = DMaps[hero_scr->sidewarpdmap[index]].map;
3562 544 screen = hero_scr->sidewarpscr[index] + DMaps[hero_scr->sidewarpdmap[index]].xoff;
3563 544 }
3564
3565 nowarp:
3566
4/4
✓ Branch 0 taken 5518 times.
✓ Branch 1 taken 64 times.
✓ Branch 2 taken 112 times.
✓ Branch 3 taken 5406 times.
5582 if(screen<0||screen>=128)
3567 176 return {-1, -1};
3568
3569 5406 return {map, screen};
3570 5582 }
3571
3572 403 optional<int> nextscr_mi(int mi, int dir)
3573 {
3574 403 int map = mi/MAPSCRSNORMAL;
3575 403 int screen = mi%MAPSCRSNORMAL;
3576 403 auto [m, s] = nextscr2(map, screen, dir);
3577
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 402 times.
403 if (m == -1) return nullopt;
3578 804 return (m<<7) + s;
3579 403 }
3580
3581 2297 void bombdoor(int32_t x,int32_t y)
3582 {
3583
2/2
✓ Branch 0 taken 2276 times.
✓ Branch 1 taken 21 times.
2297 if (!is_in_world_bounds(x, y))
3584 21 return;
3585
3586 2276 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
3587 2276 mapscr* scr = rpos_handle.scr;
3588 2276 int screen = scr->screen;
3589 3084 auto [x0, y0] = translate_screen_coordinates_to_world(rpos_handle.screen);
3590 #define CHECK_RECT(x,y,rx1,ry1,rx2,ry2) (isinRect(x,y,x0+rx1,y0+ry1,x0+rx2,y0+ry2))
3591
3592
12/12
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 2197 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 69 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 69 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 69 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 69 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 69 times.
2276 if(scr->door[0]==dBOMB && CHECK_RECT(x,y,100,0,139,48))
3593 {
3594 69 scr->door[0]=dBOMBED;
3595 69 putdoor(scr, scrollbuf, 0, dBOMBED);
3596 69 setmapflag(scr, mDOOR_UP);
3597 69 markBmap(-1, screen);
3598
3599
1/2
✓ Branch 0 taken 69 times.
✗ Branch 1 not taken.
69 if(auto v = nextscr(screen, up))
3600 {
3601 69 setmapflag_mi(*v, mDOOR_DOWN);
3602 69 markBmap(-1,*v-(get_currdmap()<<7));
3603 69 }
3604 69 }
3605
3606
12/12
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 2227 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 39 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 39 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 39 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 39 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 39 times.
2276 if(scr->door[1]==dBOMB && CHECK_RECT(x,y,100,112,139,176))
3607 {
3608 39 scr->door[1]=dBOMBED;
3609 39 putdoor(scr, scrollbuf, 1, dBOMBED);
3610 39 setmapflag(scr, mDOOR_DOWN);
3611 39 markBmap(-1, rpos_handle.screen);
3612
3613
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 if(auto v = nextscr(rpos_handle.screen, down))
3614 {
3615 39 setmapflag_mi(*v, mDOOR_UP);
3616 39 markBmap(-1,*v-(get_currdmap()<<7));
3617 39 }
3618 39 }
3619
3620
12/12
✓ Branch 0 taken 67 times.
✓ Branch 1 taken 2209 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 51 times.
✓ Branch 6 taken 16 times.
✓ Branch 7 taken 51 times.
✓ Branch 8 taken 16 times.
✓ Branch 9 taken 51 times.
✓ Branch 10 taken 16 times.
✓ Branch 11 taken 51 times.
2276 if(scr->door[2]==dBOMB && CHECK_RECT(x,y,0,60,48,98))
3621 {
3622 51 scr->door[2]=dBOMBED;
3623 51 putdoor(scr, scrollbuf, 2, dBOMBED);
3624 51 setmapflag(scr, mDOOR_LEFT);
3625 51 markBmap(-1, rpos_handle.screen);
3626
3627
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(auto v = nextscr(rpos_handle.screen, left))
3628 {
3629 51 setmapflag_mi(*v, mDOOR_RIGHT);
3630 51 markBmap(-1,*v-(get_currdmap()<<7));
3631 51 }
3632 51 }
3633
3634
12/12
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 2190 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 72 times.
✓ Branch 6 taken 14 times.
✓ Branch 7 taken 72 times.
✓ Branch 8 taken 14 times.
✓ Branch 9 taken 72 times.
✓ Branch 10 taken 14 times.
✓ Branch 11 taken 72 times.
2276 if(scr->door[3]==dBOMB && CHECK_RECT(x,y,192,60,240,98))
3635 {
3636 72 scr->door[3]=dBOMBED;
3637 72 putdoor(scr, scrollbuf, 3, dBOMBED);
3638 72 setmapflag(scr, mDOOR_RIGHT);
3639 72 markBmap(-1, rpos_handle.screen);
3640
3641
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 if(auto v = nextscr(rpos_handle.screen, right))
3642 {
3643 72 setmapflag_mi(*v, mDOOR_LEFT);
3644 72 markBmap(-1,*v-(get_currdmap()<<7));
3645 72 }
3646 72 }
3647 2297 }
3648
3649 7120005313 void draw_cmb(BITMAP* dest, int32_t x, int32_t y, int32_t cid, int32_t cset,
3650 bool over, bool transp)
3651 {
3652 7120005313 auto& cmb = combobuf[cid];
3653
2/2
✓ Branch 0 taken 95840 times.
✓ Branch 1 taken 7119909473 times.
7120005313 if(cmb.animflags & AF_EDITOR_ONLY)
3654 95840 return;
3655
2/2
✓ Branch 0 taken 3924727567 times.
✓ Branch 1 taken 3195181906 times.
7119909473 if(over)
3656 {
3657
2/2
✓ Branch 0 taken 841117 times.
✓ Branch 1 taken 3923886450 times.
3924727567 if(cmb.animflags & AF_TRANSPARENT)
3658 841117 transp = !transp;
3659
2/2
✓ Branch 0 taken 328633561 times.
✓ Branch 1 taken 3596094006 times.
3924727567 if(transp)
3660 328633561 overcombotranslucent(dest, x, y, cid, cset, 128);
3661 3596094006 else overcombo(dest, x, y, cid, cset);
3662 3924727567 }
3663 3195181906 else putcombo(dest, x, y, cid, cset);
3664 7120005313 }
3665 7120013761 void draw_cmb_pos(BITMAP* dest, int32_t x, int32_t y, rpos_t rpos, int32_t cid,
3666 int32_t cset, byte layer, bool over, bool transp)
3667 {
3668
2/2
✓ Branch 0 taken 847534117 times.
✓ Branch 1 taken 6272479644 times.
7120013761 if (rpos != rpos_t::None)
3669 {
3670 6272479644 rpos_t plrpos = COMBOPOS_REGION_B(Hero.x+8, Hero.y+8);
3671
2/2
✓ Branch 0 taken 749524 times.
✓ Branch 1 taken 6271730120 times.
6272479644 if (plrpos != rpos_t::None)
3672 {
3673 6271730120 bool dosw = false;
3674
4/4
✓ Branch 0 taken 67998 times.
✓ Branch 1 taken 6271662122 times.
✓ Branch 2 taken 59550 times.
✓ Branch 3 taken 8448 times.
6271730120 if (rpos == hooked_comborpos && (hooked_layerbits & (1<<layer)))
3675 {
3676
1/2
✓ Branch 0 taken 8448 times.
✗ Branch 1 not taken.
8448 if(hooked_undercombos[layer] > -1)
3677 {
3678 draw_cmb(dest, x, y,
3679 hooked_undercombos[layer], hooked_undercombos[layer+7], over, transp);
3680 }
3681 8448 dosw = true;
3682 8448 }
3683
4/4
✓ Branch 0 taken 35601615 times.
✓ Branch 1 taken 6236120057 times.
✓ Branch 2 taken 8448 times.
✓ Branch 3 taken 35593167 times.
6271721672 else if (rpos == plrpos && (hooked_layerbits & (1<<(layer+8))))
3684 {
3685 8448 dosw = true;
3686 8448 }
3687
2/2
✓ Branch 0 taken 6271713224 times.
✓ Branch 1 taken 16896 times.
6271730120 if (dosw)
3688 {
3689
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 16896 times.
✗ Branch 3 not taken.
16896 switch (Hero.switchhookstyle)
3690 {
3691 default: case swPOOF:
3692 break; //Nothing special here
3693 case swFLICKER:
3694 {
3695
2/2
✓ Branch 0 taken 8448 times.
✓ Branch 1 taken 8448 times.
16896 if(abs(Hero.switchhookclk-33)&0b1000)
3696 8448 break; //Drawn this frame
3697 8448 return; //Not drawn this frame
3698 }
3699 case swRISE:
3700 {
3701 //Draw rising up
3702 y -= 8-(abs(Hero.switchhookclk-32)/4);
3703 break;
3704 }
3705 }
3706 8448 }
3707 6271721672 }
3708 6272471196 }
3709
3710 7120005313 draw_cmb(dest, x, y, cid, cset, over, transp);
3711 7120013761 }
3712
3713 // `draw_cmb_pos` only does meaningful work if the combo being drawn is within the bounds of
3714 // the `bmp` bitmap. However, even getting to the point where `puttile16` (for example) knows
3715 // to cull is somewhat expensive. Since it can only draw 16x16 pixels, we can do the equivalent
3716 // culling here by determining the rows/columns that are within the bitmap bounds. This nets
3717 // on the order of ~30 FPS in uncapped mode on my machine, depending on the viewport/region size.
3718 //
3719 // These two inequalities must be true for `draw_cmb_pos` to do anything useful:
3720 //
3721 // -16 < comboPositionX*16 + x < bitmapWidth
3722 // -16 < comboPositionY*16 + y < bitmapHeight
3723 //
3724 // The following start/end values are derived directly from the above.
3725 //
3726 // `x` and `y` are the offsets the combos will be drawn into the bitmap.
3727 44035950 static void get_bounds_for_draw_cmb_calls(BITMAP* bmp, int x, int y, int& start_x, int& end_x, int& start_y, int& end_y)
3728 {
3729 // if (bmp->clip)
3730 // {
3731 // start_x = MAX(0, ceil((bmp->cl - 15 - x) / 16.0));
3732 // end_x = MIN(16, ceil((bmp->cr - x) / 16.0));
3733 // start_y = MAX(0, ceil((bmp->ct - 15 - y) / 16.0));
3734 // end_y = MIN(11, ceil((bmp->cb - y) / 16.0));
3735 // return;
3736 // }
3737
3738
2/2
✓ Branch 0 taken 2404962 times.
✓ Branch 1 taken 41630988 times.
44035950 start_x = MAX(0, ceil((-15 - x) / 16.0));
3739
2/2
✓ Branch 0 taken 2412938 times.
✓ Branch 1 taken 41623012 times.
44035950 end_x = MIN(16, ceil((bmp->w - x) / 16.0));
3740
2/2
✓ Branch 0 taken 42497400 times.
✓ Branch 1 taken 1538550 times.
44035950 start_y = MAX(0, ceil((-15 - y) / 16.0));
3741
2/2
✓ Branch 0 taken 1874536 times.
✓ Branch 1 taken 42161414 times.
44035950 end_y = MIN(11, ceil((bmp->h - y) / 16.0));
3742 44035950 }
3743
3744 195720106 void do_ffc_layer(BITMAP* bmp, int32_t layer, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3745 {
3746
1/2
✓ Branch 0 taken 195720106 times.
✗ Branch 1 not taken.
195720106 if(!show_ffcs) return;
3747 195720106 mapscr* base_scr = screen_handle.base_scr;
3748
3749 195720106 y += playing_field_offset;
3750
3751 195720106 bool is_overhead = layer == -1000;
3752
2/2
✓ Branch 0 taken 53249630 times.
✓ Branch 1 taken 142470476 times.
195720106 bool is_bg_layer = layer < 0 && !is_overhead;
3753
2/2
✓ Branch 0 taken 35535090 times.
✓ Branch 1 taken 160185016 times.
195720106 int real_layer = is_bg_layer ? abs(layer) : layer;
3754
2/2
✓ Branch 0 taken 195720106 times.
✓ Branch 1 taken 5610067558 times.
5805787664 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3755 {
3756
2/2
✓ Branch 0 taken 217455144 times.
✓ Branch 1 taken 5392612414 times.
5610067558 if (base_scr->ffcs[i].data == 0)
3757 5392612414 continue;
3758
3/4
✓ Branch 0 taken 39536116 times.
✓ Branch 1 taken 177919028 times.
✓ Branch 2 taken 39536116 times.
✗ Branch 3 not taken.
217455144 if (is_bg_layer && base_scr->ffcs[i].layer == layer)
3759 ; // ffc is set negative, skip bg layer flag checks
3760 else
3761 {
3762
4/4
✓ Branch 0 taken 39536089 times.
✓ Branch 1 taken 177919055 times.
✓ Branch 2 taken 19768058 times.
✓ Branch 3 taken 19768031 times.
217455144 if(real_layer == 2 && (is_bg_layer != XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG)))
3763 19768031 continue;
3764
4/4
✓ Branch 0 taken 39535883 times.
✓ Branch 1 taken 158151230 times.
✓ Branch 2 taken 19768058 times.
✓ Branch 3 taken 19767825 times.
197687113 else if (real_layer == 3 && (is_bg_layer != XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)))
3765 19767825 continue;
3766
4/4
✓ Branch 0 taken 158156192 times.
✓ Branch 1 taken 19763096 times.
✓ Branch 2 taken 19768058 times.
✓ Branch 3 taken 138388134 times.
177919288 if (real_layer > -1 && base_scr->ffcs[i].layer != real_layer)
3767 138388134 continue;
3768 }
3769
3770
6/6
✓ Branch 0 taken 3311080 times.
✓ Branch 1 taken 36220074 times.
✓ Branch 2 taken 5110 times.
✓ Branch 3 taken 3305970 times.
✓ Branch 4 taken 2626 times.
✓ Branch 5 taken 2484 times.
39531154 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3771 2484 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3772
3773 39528670 base_scr->ffcs[i].draw_ffc(bmp, x, y, is_overhead);
3774 39528670 }
3775 195720106 }
3776 177528574 void _do_current_ffc_layer(BITMAP* bmp, int32_t layer)
3777 {
3778
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 177528574 times.
177528574 if(!show_ffcs) return;
3779 359982090 for_every_base_screen_in_region([&](mapscr* base_scr, unsigned int region_scr_x, unsigned int region_scr_y) {
3780 182453516 screen_handle_t handle = {base_scr, base_scr, base_scr->screen, 0};
3781 182453516 do_ffc_layer(bmp, layer, handle, 0, 0);
3782 182453516 });
3783 177528574 }
3784 110564490 void do_scrolling_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3785 {
3786 110564490 mapscr* scr = screen_handle.scr;
3787 110564490 mapscr* base_scr = screen_handle.base_scr;
3788
3789
4/4
✓ Branch 0 taken 69334564 times.
✓ Branch 1 taken 41229926 times.
✓ Branch 2 taken 41229926 times.
✓ Branch 3 taken 110564490 times.
110564490 if (type == -3 || type == -4)
3790 {
3791 82459852 y += playing_field_offset;
3792
3793
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
82459852 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3794 {
3795 if (base_scr->ffcs[i].data == 0)
3796 continue;
3797
3798 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3799 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3800
3801 base_scr->ffcs[i].draw_ffc(bmp, x, y, (type==-4));
3802 }
3803 return;
3804 }
3805
3806 110564490 x -= viewport.x;
3807 110564490 y -= viewport.y - playing_field_offset;
3808
3809 110564490 bool over = true, transp = false;
3810 110564490 int layer = screen_handle.layer;
3811
3812
7/8
✓ Branch 0 taken 86296232 times.
✓ Branch 1 taken 24268258 times.
✓ Branch 2 taken 15026723 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 62975483 times.
✓ Branch 5 taken 23320749 times.
✓ Branch 6 taken 3907648 times.
✓ Branch 7 taken 5333887 times.
110564490 switch(type ? type : layer)
3813 {
3814 case -2: //push blocks
3815
2/2
✓ Branch 0 taken 21745557 times.
✓ Branch 1 taken 41229926 times.
62975483 if (scr)
3816 {
3817
2/2
✓ Branch 0 taken 3827218032 times.
✓ Branch 1 taken 62318575 times.
3863254799 for(int32_t i=0; i<176; i++)
3818 {
3819 3827218032 int32_t mf=scr->sflag[i], mf2 = combobuf[scr->data[i]].flag;
3820
3821
10/10
✓ Branch 0 taken 3827047688 times.
✓ Branch 1 taken 170344 times.
✓ Branch 2 taken 3825570483 times.
✓ Branch 3 taken 1477205 times.
✓ Branch 4 taken 3824937244 times.
✓ Branch 5 taken 633239 times.
✓ Branch 6 taken 53394531 times.
✓ Branch 7 taken 3771542713 times.
✓ Branch 8 taken 100280201 times.
✓ Branch 9 taken 57139160 times.
3870809545 if(mf==mfPUSHUD || mf==mfPUSH4 || mf==mfPUSHED || ((mf>=mfPUSHLR)&&(mf<=mfPUSHRINS))
3822
6/8
✓ Branch 0 taken 3822054595 times.
✓ Branch 1 taken 50511882 times.
✓ Branch 2 taken 3822054595 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3822054595 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 43591513 times.
✓ Branch 7 taken 3778463082 times.
3824937244 || mf2==mfPUSHUD || mf2==mfPUSH4 || mf2==mfPUSHED || ((mf2>=mfPUSHLR)&&(mf2<=mfPUSHRINS)))
3823 {
3824
4/4
✓ Branch 0 taken 5124570 times.
✓ Branch 1 taken 782430 times.
✓ Branch 2 taken 3849 times.
✓ Branch 3 taken 5120721 times.
206467402 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3825 5907000 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3826 5907000 }
3827 3841509242 }
3828 62318575 }
3829 103548501 return;
3830
3831 case -1: //over combo
3832
1/2
✓ Branch 0 taken 23320749 times.
✗ Branch 1 not taken.
23320749 if (scr)
3833 {
3834
2/2
✓ Branch 0 taken 4104451824 times.
✓ Branch 1 taken 23320749 times.
4127772573 for(int32_t i=0; i<176; i++)
3835 {
3836
2/2
✓ Branch 0 taken 4085121904 times.
✓ Branch 1 taken 19329920 times.
4104451824 if(combo_class_buf[combobuf[scr->data[i]].type].overhead)
3837 {
3838
4/4
✓ Branch 0 taken 15574819 times.
✓ Branch 1 taken 3755101 times.
✓ Branch 2 taken 22336 times.
✓ Branch 3 taken 15552483 times.
19329920 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3839 19329920 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3840 19329920 }
3841 4104451824 }
3842 23320749 }
3843 23320749 return;
3844
3845 case 1:
3846 case 4:
3847 case 5:
3848 case 6:
3849
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15026723 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
15026723 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3850 {
3851
1/2
✓ Branch 0 taken 15026723 times.
✗ Branch 1 not taken.
15026723 if (scr)
3852 {
3853
2/2
✓ Branch 0 taken 13331916 times.
✓ Branch 1 taken 1694807 times.
15026723 if(base_scr->layeropacity[layer-1]!=255)
3854 1694807 transp = true;
3855 15026723 break;
3856 }
3857 }
3858 return;
3859
3860 case 2:
3861
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3907648 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3907648 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3862 {
3863
1/2
✓ Branch 0 taken 3907648 times.
✗ Branch 1 not taken.
3907648 if (scr)
3864 {
3865
2/2
✓ Branch 0 taken 3671362 times.
✓ Branch 1 taken 236286 times.
3907648 if(base_scr->layeropacity[layer-1]!=255)
3866 236286 transp = true;
3867
3868
2/2
✓ Branch 0 taken 3760193 times.
✓ Branch 1 taken 147455 times.
3907648 if(XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3869 147455 over = false;
3870
3871 3907648 break;
3872 }
3873 }
3874 return;
3875
3876 case 3:
3877
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5333887 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
5333887 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3878 {
3879
1/2
✓ Branch 0 taken 5333887 times.
✗ Branch 1 not taken.
5333887 if (scr)
3880 {
3881
2/2
✓ Branch 0 taken 5258611 times.
✓ Branch 1 taken 75276 times.
5333887 if(base_scr->layeropacity[layer-1]!=255)
3882 75276 transp = true;
3883
3884
2/2
✓ Branch 0 taken 36654 times.
✓ Branch 1 taken 237618 times.
5333887 if(XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)
3885
2/2
✓ Branch 0 taken 274272 times.
✓ Branch 1 taken 5059615 times.
5333887 && !XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3886 237618 over = false;
3887
3888 5333887 break;
3889 }
3890 }
3891 return;
3892 }
3893
3894 int start_x, end_x, start_y, end_y;
3895 24268258 get_bounds_for_draw_cmb_calls(bmp, x, y, start_x, end_x, start_y, end_y);
3896
2/2
✓ Branch 0 taken 24268258 times.
✓ Branch 1 taken 257485684 times.
281753942 for (int cy = start_y; cy < end_y; cy++)
3897 {
3898
2/2
✓ Branch 0 taken 3898086039 times.
✓ Branch 1 taken 257485684 times.
4155571723 for (int cx = start_x; cx < end_x; cx++)
3899 {
3900 3898086039 int i = cx + cy*16;
3901
4/4
✓ Branch 0 taken 3441235004 times.
✓ Branch 1 taken 456851035 times.
✓ Branch 2 taken 11831072 times.
✓ Branch 3 taken 3429403932 times.
3898086039 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3902 3898086039 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, over, transp);
3903 3898086039 }
3904 257485684 }
3905 69334564 }
3906
3907 279535975 bool lenscheck(mapscr* scr, int layer)
3908 {
3909
4/4
✓ Branch 0 taken 279359403 times.
✓ Branch 1 taken 176572 times.
✓ Branch 2 taken 176572 times.
✓ Branch 3 taken 279535975 times.
279535975 if(layer < 0 || layer > 6) return true;
3910
2/2
✓ Branch 0 taken 259692525 times.
✓ Branch 1 taken 19843450 times.
279535975 if(get_qr(qr_OLD_LENS_LAYEREFFECT))
3911 {
3912
2/2
✓ Branch 0 taken 209793109 times.
✓ Branch 1 taken 49899416 times.
259692525 if(!layer) return true;
3913
8/8
✓ Branch 0 taken 34936541 times.
✓ Branch 1 taken 174856568 times.
✓ Branch 2 taken 258970 times.
✓ Branch 3 taken 34677571 times.
✓ Branch 4 taken 146134 times.
✓ Branch 5 taken 259680 times.
✓ Branch 6 taken 326536 times.
✓ Branch 7 taken 34497169 times.
209793109 if((layer==(int32_t)(scr->lens_layer&7)+1) && ((scr->lens_layer&llLENSSHOWS && !lensclk) || (scr->lens_layer&llLENSHIDES && lensclk)))
3914 586216 return false;
3915 209353737 }
3916 else
3917 {
3918
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 19843450 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 19843450 times.
19843450 if((lensclk ? scr->lens_hide : scr->lens_show) & (1<<layer))
3919 return false;
3920 }
3921 229197187 return true;
3922 279359403 }
3923
3924 165168059 void do_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3925 {
3926 165168059 bool showlayer = true;
3927 165168059 mapscr* base_scr = screen_handle.base_scr;
3928 165168059 int layer = screen_handle.layer;
3929
2/2
✓ Branch 0 taken 46586195 times.
✓ Branch 1 taken 118581864 times.
165168059 int target = type ? type : layer;
3930
3/4
✓ Branch 0 taken 118581864 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 22483787 times.
✓ Branch 3 taken 24102408 times.
165168059 switch(target)
3931 {
3932 case -2:
3933
1/2
✓ Branch 0 taken 22483787 times.
✗ Branch 1 not taken.
22483787 if(!show_layer_push)
3934 showlayer = false;
3935 22483787 break;
3936
3937 case -1:
3938
1/2
✓ Branch 0 taken 24102408 times.
✗ Branch 1 not taken.
24102408 if(!show_layer_over)
3939 showlayer = false;
3940 24102408 break;
3941
3942 case 1: case 2: case 3:
3943 case 4: case 5: case 6:
3944 118581864 showlayer = show_layers[target];
3945 118581864 break;
3946 }
3947
3948
2/2
✓ Branch 0 taken 46586195 times.
✓ Branch 1 taken 118581864 times.
165168059 if(!type)
3949 {
3950
2/2
✓ Branch 0 taken 118445666 times.
✓ Branch 1 taken 136198 times.
118581864 if(!lenscheck(base_scr,layer))
3951 136198 showlayer = false;
3952 118581864 }
3953
3954
2/2
✓ Branch 0 taken 136198 times.
✓ Branch 1 taken 165031861 times.
165168059 if(showlayer)
3955 {
3956
6/6
✓ Branch 0 taken 69426512 times.
✓ Branch 1 taken 95605349 times.
✓ Branch 2 taken 24360206 times.
✓ Branch 3 taken 45066306 times.
✓ Branch 4 taken 91948 times.
✓ Branch 5 taken 24268258 times.
165031861 if (screen_handle.scr && (type || !(base_scr->hidelayers & (1 << (layer)))))
3957 {
3958 69334564 do_scrolling_layer(bmp, type, screen_handle, x, y);
3959
4/4
✓ Branch 0 taken 24268258 times.
✓ Branch 1 taken 45066306 times.
✓ Branch 2 taken 22269756 times.
✓ Branch 3 taken 1998502 times.
69334564 if(!type && !get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
3960
2/2
✓ Branch 0 taken 1997926 times.
✓ Branch 1 taken 576 times.
1999078 if(mblock2.draw(bmp,layer))
3961 576 do_primitives(bmp, SPLAYER_MOVINGBLOCK);
3962 69334564 }
3963 165031861 }
3964 165168059 }
3965
3966 107036242 void do_layer_primitives(BITMAP *bmp, int32_t layer)
3967 {
3968 107036242 bool showlayer = true;
3969
3970
2/4
✓ Branch 0 taken 107036242 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 107036242 times.
107036242 if(layer >= 0 && layer <= 6)
3971 {
3972 107036242 showlayer = show_layers[layer];
3973
3974
2/2
✓ Branch 0 taken 106909640 times.
✓ Branch 1 taken 126602 times.
107036242 if(!lenscheck(origin_scr,layer))
3975 126602 showlayer = false;
3976 107036242 }
3977
3978
2/2
✓ Branch 0 taken 126602 times.
✓ Branch 1 taken 106909640 times.
107036242 if (showlayer)
3979 106909640 do_primitives(bmp, layer);
3980 107036242 }
3981
3982 // Called by do_walkflags
3983 void put_walkflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
3984 {
3985 newcombo const &c = combobuf[cmbdat];
3986
3987 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
3988
3989 int32_t xx = x-xofs;
3990 int32_t yy = y+playing_field_offset-yofs;
3991
3992 int32_t bridgedetected = 0;
3993
3994 for(int32_t i=0; i<4; i++)
3995 {
3996 int32_t tx=((i&2)<<2)+xx - viewport.x;
3997 int32_t ty=((i&1)<<3)+yy - viewport.y;
3998 int32_t tx2=((i&2)<<2)+x - viewport.x;
3999 int32_t ty2=((i&1)<<3)+y - viewport.y;
4000 for (int32_t j = lyr-1; j <= 1; j++)
4001 {
4002 if (get_qr(qr_OLD_BRIDGE_COMBOS))
4003 {
4004 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && !_walkflag_layer(tx2,ty2,j))
4005 {
4006 bridgedetected |= (1<<i);
4007 }
4008 }
4009 else
4010 {
4011 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && _effectflag_layer(tx2,ty2,j))
4012 {
4013 bridgedetected |= (1<<i);
4014 }
4015 }
4016 }
4017 if ((bridgedetected & (1<<i)))
4018 {
4019 if (i >= 3) break;
4020 else continue;
4021 }
4022 bool doladdercheck = true;
4023
4024 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4025 {
4026 for(int32_t k=0; k<8; k+=2)
4027 for(int32_t j=0; j<8; j+=2)
4028 if(((k+j)/2)%2)
4029 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,makecol(85,85,255));
4030 }
4031 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4032 {
4033 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4034 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4035 rectfill(dest,tx,ty,tx+7,ty+7,makecol(85,85,255));
4036 else rectfill(dest,tx,ty,tx+7,ty+7,makecol(170,170,170));
4037 }
4038
4039 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4040 {
4041 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4042 {
4043 for(int32_t k=0; k<8; k+=2)
4044 for(int32_t j=0; j<8; j+=2)
4045 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,((k+j)/2)%2 ? makecol(165,105,8) : makecol(170,170,170));
4046 }
4047 else
4048 {
4049 int32_t color = makecol(178,36,36);
4050
4051 if(isstepable(cmbdat)&& (!doladdercheck))
4052 color=makecol(165,105,8);
4053 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4054 color=makecol(170,170,170);
4055
4056 rectfill(dest,tx,ty,tx+7,ty+7,color);
4057 }
4058 }
4059 }
4060
4061 // Draw damage combos
4062 bool dmg = combo_class_buf[combobuf[MAPCOMBO2(-1,xx,yy)].type].modify_hp_amount
4063 || combo_class_buf[combobuf[MAPCOMBO2(0,xx,yy)].type].modify_hp_amount
4064 || combo_class_buf[combobuf[MAPCOMBO2(1,xx,yy)].type].modify_hp_amount;
4065
4066 if(dmg)
4067 {
4068 int32_t color = makecol(255,255,0);
4069 if (bridgedetected <= 0)
4070 {
4071 for(int32_t k=0; k<16; k+=2)
4072 for(int32_t j=0; j<16; j+=2)
4073 if(((k+j)/2)%2)
4074 {
4075 int32_t x0 = x - viewport.x;
4076 int32_t y0 = y - viewport.y;
4077 rectfill(dest,x0+k,y0+j,x0+k+1,y0+j+1,color);
4078 }
4079 }
4080 else
4081 {
4082 for(int32_t i=0; i<4; i++)
4083 {
4084 if (!(bridgedetected & (1<<i)))
4085 {
4086 int32_t tx=((i&2)<<2)+x - viewport.x;
4087 int32_t ty=((i&1)<<3)+y - viewport.y;
4088 for(int32_t k=0; k<8; k+=2)
4089 for(int32_t j=0; j<8; j+=2)
4090 if((k+j)%4 < 2) rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,color);
4091 }
4092 }
4093 }
4094 }
4095 }
4096 static void put_walkflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4097 {
4098 ALLEGRO_COLOR col_solid = al_map_rgba(178,36,36,info_opacity);
4099 ALLEGRO_COLOR col_water1 = al_map_rgba(85,85,255,info_opacity);
4100 ALLEGRO_COLOR col_lhook = al_map_rgba(170,170,170,info_opacity);
4101 ALLEGRO_COLOR col_stepable = al_map_rgba(165,105,8,info_opacity);
4102 ALLEGRO_COLOR col_dmg = al_map_rgba(255,255,0,info_opacity);
4103 newcombo const &c = combobuf[cmbdat];
4104
4105 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
4106
4107 int32_t xx = x-viewport.x;
4108 int32_t yy = y+playing_field_offset-viewport.y;
4109
4110 int32_t bridgedetected = 0;
4111
4112 // Draw damage combos
4113 bool dmg = combo_class_buf[c.type].modify_hp_amount;
4114
4115 for(int32_t i=0; i<4; i++)
4116 {
4117 int32_t tx=((i&2)<<2)+xx;
4118 int32_t ty=((i&1)<<3)+yy;
4119 int32_t tx2=((i&2)<<2)+x;
4120 int32_t ty2=((i&1)<<3)+y;
4121 for (int32_t m = lyr-1; m <= 1; m++)
4122 {
4123 if (get_qr(qr_OLD_BRIDGE_COMBOS))
4124 {
4125 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && !_walkflag_layer(tx2, ty2, m))
4126 {
4127 bridgedetected |= (1<<i);
4128 }
4129 }
4130 else
4131 {
4132 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && _effectflag_layer(tx2, ty2, m))
4133 {
4134 bridgedetected |= (1<<i);
4135 }
4136 }
4137 }
4138 if ((bridgedetected & (1<<i)))
4139 continue;
4140 bool doladdercheck = true;
4141
4142 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4143 {
4144 for(int32_t k=0; k<8; k+=2)
4145 for(int32_t j=0; j<8; j+=2)
4146 if(((k+j)/2)%2)
4147 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_water1);
4148 }
4149 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4150 {
4151 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4152 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4153 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_water1);
4154 else al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_lhook);
4155 }
4156
4157 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4158 {
4159 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4160 {
4161 for(int32_t k=0; k<8; k+=2)
4162 for(int32_t j=0; j<8; j+=2)
4163 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,((k+j)/2)%2 ? col_stepable : col_lhook);
4164 }
4165 else
4166 {
4167 ALLEGRO_COLOR* color = &col_solid;
4168
4169 if(isstepable(cmbdat)&& (!doladdercheck))
4170 color=&col_stepable;
4171 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4172 color=&col_lhook;
4173
4174 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,*color);
4175 }
4176 }
4177
4178 if(dmg)
4179 {
4180 for(int32_t k=0; k<8; k+=2)
4181 for(int32_t j=0; j<8; j+=2)
4182 if((k+j)%4 < 2) al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_dmg);
4183 }
4184 }
4185 }
4186
4187 void put_effectflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
4188 {
4189 newcombo const &c = combobuf[cmbdat];
4190
4191 int32_t xx = x-xofs-viewport.x;
4192 int32_t yy = y+playing_field_offset-yofs-viewport.y;
4193
4194 for(int32_t i=0; i<4; i++)
4195 {
4196 int32_t tx=((i&2)<<2)+xx;
4197 int32_t ty=((i&1)<<3)+yy;
4198
4199 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4200 {
4201 int32_t color = vc(10);
4202
4203 rectfill(dest,tx,ty,tx+7,ty+7,color);
4204 }
4205 }
4206 }
4207 static void put_effectflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4208 {
4209 ALLEGRO_COLOR col_eff = al_map_rgba(85,255,85,info_opacity);
4210 newcombo const &c = combobuf[cmbdat];
4211
4212 int32_t xx = x-viewport.x;
4213 int32_t yy = y+playing_field_offset-viewport.y;
4214
4215 for(int32_t i=0; i<4; i++)
4216 {
4217 int32_t tx=((i&2)<<2)+xx;
4218 int32_t ty=((i&1)<<3)+yy;
4219
4220 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4221 {
4222 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_eff);
4223 }
4224 }
4225 }
4226
4227 void draw_ladder_platform(BITMAP* dest, int32_t x, int32_t y, int32_t c)
4228 {
4229 for(auto cx = 0; cx < 256; cx += 16)
4230 {
4231 for(auto cy = 0; cy < 176; cy += 16)
4232 {
4233 if(isSVLadder(cx,cy))
4234 {
4235 auto nx = cx+x, ny = cy+y;
4236 if(cy && !isSVLadder(cx,cy-16))
4237 line(dest,nx,ny,nx+15,ny,c);
4238 rectfill(dest,nx,ny,nx+3,ny+15,c);
4239 rectfill(dest,nx+12,ny,nx+15,ny+15,c);
4240 rectfill(dest,nx+4,ny+2,nx+11,ny+5,c);
4241 rectfill(dest,nx+4,ny+10,nx+11,ny+13,c);
4242 }
4243 else if(isSVPlatform(cx,cy))
4244 {
4245 line(dest,cx+x,cy+y,cx+x+15,cy+y,c);
4246 }
4247 }
4248 }
4249 }
4250 void draw_ladder_platform_a5(int32_t x, int32_t y, ALLEGRO_COLOR c)
4251 {
4252 for(auto cx = 0; cx < 256; cx += 16)
4253 {
4254 for(auto cy = 0; cy < 176; cy += 16)
4255 {
4256 if(isSVLadder(cx,cy))
4257 {
4258 auto nx = cx+x, ny = cy+y;
4259 if(cy && !isSVLadder(cx,cy-16))
4260 al_draw_line(nx,ny,nx+15,ny,c,1);
4261 al_draw_filled_rectangle(nx,ny,nx+4,ny+16,c);
4262 al_draw_filled_rectangle(nx+12,ny,nx+16,ny+16,c);
4263 al_draw_filled_rectangle(nx+4,ny+2,nx+12,ny+6,c);
4264 al_draw_filled_rectangle(nx+4,ny+10,nx+12,ny+14,c);
4265 }
4266 else if(isSVPlatform(cx,cy))
4267 {
4268 al_draw_line(cx+x,cy+y,cx+x+15,cy+y,c,1);
4269 }
4270 }
4271 }
4272 }
4273
4274 // Walkflags L4 cheat
4275 void do_walkflags(const screen_handles_t& screen_handles, int32_t x, int32_t y)
4276 {
4277 if (!show_walkflags)
4278 return;
4279
4280 start_info_bmp();
4281
4282 mapscr* scr = screen_handles[0].base_scr;
4283 for(int32_t i=0; i<176; i++)
4284 {
4285 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4286 }
4287
4288 for(int32_t k=0; k<2; k++)
4289 {
4290 scr = screen_handles[k + 1].scr;
4291
4292 if (scr)
4293 {
4294 for(int32_t i=0; i<176; i++)
4295 {
4296 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], k%2+1);
4297 }
4298 }
4299 }
4300
4301 end_info_bmp();
4302 }
4303
4304 void do_walkflags(int32_t x, int32_t y)
4305 {
4306 if (!show_walkflags)
4307 return;
4308
4309 x += -viewport.x;
4310 y += playing_field_offset - viewport.y;
4311
4312 start_info_bmp();
4313
4314 draw_ladder_platform_a5(x,y,al_map_rgba(165,105,8,info_opacity));
4315 draw_solid_objects_a5(x,y,al_map_rgba(178,36,36,info_opacity));
4316 draw_slopes_a5(x,y,al_map_rgba(255,85,255,info_opacity));
4317
4318 end_info_bmp();
4319 }
4320
4321 // Effectflags L4 cheat
4322 void do_effectflags(mapscr* scr, int32_t x, int32_t y)
4323 {
4324 if(show_effectflags)
4325 {
4326 start_info_bmp();
4327
4328 for(int32_t i=0; i<176; i++)
4329 {
4330 put_effectflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4331 }
4332
4333 end_info_bmp();
4334 }
4335 }
4336
4337 400489 void calc_darkroom_combos(mapscr* scr, int offx, int offy)
4338 {
4339 400489 int map = scr->map;
4340 400489 int screen = scr->screen;
4341
4342
2/2
✓ Branch 0 taken 2803423 times.
✓ Branch 1 taken 400489 times.
3203912 for(int32_t lyr = 0; lyr < 7; ++lyr)
4343 {
4344 2803423 mapscr* scr = get_scr_layer(map, screen, lyr);
4345
2/2
✓ Branch 0 taken 1829718 times.
✓ Branch 1 taken 973705 times.
2803423 if (!scr->is_valid()) continue;
4346
4347
2/2
✓ Branch 0 taken 322030368 times.
✓ Branch 1 taken 1829718 times.
323860086 for(int32_t q = 0; q < 176; ++q)
4348 {
4349 322030368 newcombo const& cmb = combobuf[scr->data[q]];
4350
2/2
✓ Branch 0 taken 320498295 times.
✓ Branch 1 taken 1532073 times.
322030368 if(cmb.type == cTORCH)
4351 {
4352 1532073 do_torch_combo(cmb, COMBOX(q)+8+offx, COMBOY(q)+8+offy, darkscr_bmp);
4353 1532073 }
4354 322030368 }
4355 1829718 }
4356 400489 }
4357
4358 400489 void calc_darkroom_ffcs(mapscr* scr, int offx, int offy)
4359 {
4360 400489 word c = scr->numFFC();
4361
2/2
✓ Branch 0 taken 704965 times.
✓ Branch 1 taken 400489 times.
1105454 for(int q = 0; q < c; ++q)
4362 {
4363 704965 newcombo const& cmb = combobuf[scr->ffcs[q].data];
4364
2/2
✓ Branch 0 taken 690157 times.
✓ Branch 1 taken 14808 times.
704965 if(cmb.type == cTORCH)
4365 {
4366 14808 int cx = scr->ffcs[q].x.getInt()+(scr->ffEffectWidth(q)/2)+offx;
4367 14808 int cy = (scr->ffcs[q].y.getInt())+(scr->ffEffectHeight(q)/2)+offy;
4368 14808 do_torch_combo(cmb, cx, cy, darkscr_bmp);
4369 14808 }
4370 704965 }
4371 400489 }
4372
4373 struct nearby_screen_t
4374 {
4375 int screen;
4376 int offx;
4377 int offy;
4378 screen_handles_t screen_handles;
4379 };
4380 typedef std::vector<nearby_screen_t> nearby_screens_t;
4381
4382 16081834 static nearby_screens_t get_nearby_screens_non_scrolling_region()
4383 {
4384 16081834 nearby_screens_t nearby_screens;
4385
4386 16081834 mapscr* base_scr = origin_scr;
4387
1/2
✓ Branch 0 taken 16081834 times.
✗ Branch 1 not taken.
16081834 auto& nearby_screen = nearby_screens.emplace_back();
4388 16081834 nearby_screen.screen = cur_screen;
4389
1/2
✓ Branch 0 taken 16081834 times.
✗ Branch 1 not taken.
16081834 nearby_screen.screen_handles = create_screen_handles(base_scr);
4390
4391 16081834 return nearby_screens;
4392
1/2
✓ Branch 0 taken 16081834 times.
✗ Branch 1 not taken.
16081834 }
4393
4394 48296 static nearby_screens_t get_nearby_screens_scrolling_region()
4395 {
4396 48296 nearby_screens_t nearby_screens;
4397
4398
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x0 = viewport.left() / 256;
4399
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x1 = (viewport.right() - 1) / 256;
4400
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y0 = viewport.top() / 176;
4401
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y1 = (viewport.bottom() - 1) / 176;
4402
4403
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x0 = std::clamp(screens_x0, 0, 15);
4404
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x1 = std::clamp(screens_x1, 0, 15);
4405
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y0 = std::clamp(screens_y0, 0, 8);
4406
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y1 = std::clamp(screens_y1, 0, 8);
4407
4408
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 79928 times.
128224 for (int x = screens_x0; x <= screens_x1; x++)
4409 {
4410
2/2
✓ Branch 0 taken 169672 times.
✓ Branch 1 taken 79928 times.
249600 for (int y = screens_y0; y <= screens_y1; y++)
4411 {
4412 169672 int screen = cur_screen + x + y*16;
4413
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!is_in_current_region(screen)) continue;
4414
4415
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 mapscr* base_scr = get_scr(screen);
4416
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!base_scr->is_valid()) continue;
4417
4418
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
4419
4420
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto& nearby_screen = nearby_screens.emplace_back();
4421 169672 nearby_screen.screen = screen;
4422 169672 nearby_screen.offx = offx;
4423 169672 nearby_screen.offy = offy;
4424
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 nearby_screen.screen_handles = create_screen_handles(base_scr);
4425 169672 }
4426 79928 }
4427
4428 48296 return nearby_screens;
4429
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 }
4430
4431 3658 static nearby_screens_t get_nearby_screens_smooth_maze()
4432 {
4433 3658 nearby_screens_t nearby_screens;
4434
4435
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x0 = viewport.left() / 256;
4436
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x1 = (viewport.right() - 1) / 256;
4437
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y0 = viewport.top() / 176;
4438
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y1 = (viewport.bottom() - 1) / 176;
4439
4440
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.left() < 0) screens_x0--;
4441
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.top() < 0) screens_y0--;
4442
4443
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 7308 times.
10966 for (int x = screens_x0; x <= screens_x1; x++)
4444 {
4445
2/2
✓ Branch 0 taken 18600 times.
✓ Branch 1 taken 7308 times.
25908 for (int y = screens_y0; y <= screens_y1; y++)
4446 {
4447 18600 int screen = -1;
4448 mapscr* base_scr;
4449 int offx, offy;
4450
4451 18600 mapscr* maze_scr = maze_state.scr;
4452 18600 int maze_screen = maze_scr->screen;
4453
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_x = get_region_relative_dx(maze_screen);
4454
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_y = get_region_relative_dy(maze_screen);
4455 18600 int maze_screen_dx = x - maze_screen_x;
4456 18600 int maze_screen_dy = y - maze_screen_y;
4457 18600 int exitdir = maze_scr->exitdir;
4458
4459 bool should_draw_maze_screen;
4460
2/2
✓ Branch 0 taken 9052 times.
✓ Branch 1 taken 9548 times.
18600 if (maze_state.lost)
4461 {
4462 9548 should_draw_maze_screen = true;
4463 9548 }
4464 else
4465 {
4466 9052 should_draw_maze_screen = true;
4467
4/6
✓ Branch 0 taken 9052 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6844 times.
✓ Branch 3 taken 2208 times.
✓ Branch 4 taken 6844 times.
✗ Branch 5 not taken.
9052 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != exitdir && XY_DELTA_TO_DIR(0, maze_screen_dy) != exitdir;
4468
2/2
✓ Branch 0 taken 3850 times.
✓ Branch 1 taken 5202 times.
9052 if (maze_state.enter_dir != dir_invalid)
4469
4/6
✓ Branch 0 taken 3850 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3304 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 3304 times.
✗ Branch 5 not taken.
3850 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != maze_state.enter_dir && XY_DELTA_TO_DIR(0, maze_screen_dy) != maze_state.enter_dir;
4470 }
4471
4472
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (should_draw_maze_screen)
4473 {
4474 16048 screen = maze_state.scr->screen;
4475 16048 base_scr = maze_state.scr;
4476
1/2
✓ Branch 0 taken 16048 times.
✗ Branch 1 not taken.
16048 std::tie(offx, offy) = translate_screen_coordinates_to_world(cur_screen + x + y*16);
4477 16048 }
4478
4479
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (screen == -1)
4480 {
4481 2552 screen = cur_screen + x + y*16;
4482
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!is_in_current_region(screen)) continue;
4483
4484
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 base_scr = get_scr(screen);
4485
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!base_scr->is_valid()) continue;
4486
4487
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 std::tie(offx, offy) = translate_screen_coordinates_to_world(screen);
4488 2552 }
4489
4490
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 auto& nearby_screen = nearby_screens.emplace_back();
4491 18600 nearby_screen.screen = screen;
4492 18600 nearby_screen.offx = offx;
4493 18600 nearby_screen.offy = offy;
4494
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 nearby_screen.screen_handles = create_screen_handles(base_scr);
4495 18600 }
4496 7308 }
4497
4498 3658 return nearby_screens;
4499
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 }
4500
4501 16133788 static nearby_screens_t get_nearby_screens()
4502 {
4503
4/4
✓ Branch 0 taken 9214 times.
✓ Branch 1 taken 16124574 times.
✓ Branch 2 taken 3658 times.
✓ Branch 3 taken 5556 times.
16133788 if (maze_state.active && maze_state.loopy)
4504 3658 return get_nearby_screens_smooth_maze();
4505
4506
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 16081834 times.
16130130 if (is_in_scrolling_region())
4507 48296 return get_nearby_screens_scrolling_region();
4508
4509 16081834 return get_nearby_screens_non_scrolling_region();
4510 16133788 }
4511
4512 209966575 static void for_every_nearby_screen(const nearby_screens_t& nearby_screens, const std::function <void (screen_handles_t, int, int, int)>& fn)
4513 {
4514
2/2
✓ Branch 0 taken 211751177 times.
✓ Branch 1 taken 209966575 times.
421717752 for (auto& nearby_screen : nearby_screens)
4515 211751177 fn(nearby_screen.screen_handles, nearby_screen.screen, nearby_screen.offx, nearby_screen.offy);
4516 209966575 }
4517
4518 145288604 static void draw_msgstr(byte layer, BITMAP* dest = nullptr)
4519 {
4520
2/2
✓ Branch 0 taken 32309070 times.
✓ Branch 1 taken 112979534 times.
145288604 if(layer != msgstr_layer) return;
4521
2/2
✓ Branch 0 taken 16133026 times.
✓ Branch 1 taken 16176044 times.
32309070 if(!dest) dest = framebuf;
4522
4523
2/2
✓ Branch 0 taken 1461257 times.
✓ Branch 1 taken 30847813 times.
32309070 if(!(msg_bg_display_buf->clip))
4524 {
4525 1461257 blit_msgstr_bg(dest,0,0,0,playing_field_offset,256,176);
4526 1461257 }
4527
4528
2/2
✓ Branch 0 taken 1461257 times.
✓ Branch 1 taken 30847813 times.
32309070 if(!(msg_portrait_display_buf->clip))
4529 {
4530 1461257 blit_msgstr_prt(dest,0,0,0,playing_field_offset,256,176);
4531 1461257 }
4532
4533
2/2
✓ Branch 0 taken 1488071 times.
✓ Branch 1 taken 30820999 times.
32309070 if(!(msg_txt_display_buf->clip))
4534 {
4535 1488071 blit_msgstr_fg(dest,0,0,0,playing_field_offset,256,176);
4536 1488071 }
4537 145288604 }
4538
4539 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y);
4540
4541 64535152 static void set_draw_screen_clip(BITMAP* bmp)
4542 {
4543 64535152 set_clip_rect(bmp, draw_screen_clip_rect_x1, draw_screen_clip_rect_y1, draw_screen_clip_rect_x2, draw_screen_clip_rect_y2);
4544 64535152 }
4545
4546 17580 static void draw_sprites(BITMAP* dest, set<sprite*, SpriteSorter>& sprite_set, set<sprite*, SpriteSorter>::iterator& it, word upto_z)
4547 {
4548 17580 bool checkz = upto_z != word(-1); // max value represents "infinity" height
4549
6/6
✓ Branch 0 taken 11145 times.
✓ Branch 1 taken 6435 times.
✓ Branch 2 taken 160 times.
✓ Branch 3 taken 6275 times.
✓ Branch 4 taken 12905 times.
✓ Branch 5 taken 4675 times.
17580 if(it == sprite_set.end() || (checkz && (*it)->total_z() >= upto_z))
4550 12905 return; // no sprites to draw remaining
4551 // Just clips sprites if in a repeating, smooth maze.
4552
1/2
✓ Branch 0 taken 4675 times.
✗ Branch 1 not taken.
4675 bool do_clip = maze_state.active && maze_state.loopy;
4553
4554
4555
1/2
✓ Branch 0 taken 4675 times.
✗ Branch 1 not taken.
4675 if(do_clip)
4556 {
4557 int maze_screen = maze_state.scr->screen;
4558 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4559 set_clip_rect(dest, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4560 }
4561
6/6
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 32443 times.
✓ Branch 2 taken 160 times.
✓ Branch 3 taken 32283 times.
✓ Branch 4 taken 4675 times.
✓ Branch 5 taken 30698 times.
67816 while(it != sprite_set.end() && (!checkz || (*it)->total_z() < upto_z))
4562 {
4563 30698 sprite* spr = *it;
4564
2/2
✓ Branch 0 taken 27768 times.
✓ Branch 1 taken 2930 times.
30698 if(spr == &Hero) // Draw the Hero
4565 {
4566 2930 decorations.draw2(dest,true);
4567 2930 Hero.draw(dest);
4568 2930 decorations.draw(dest,true);
4569
4570 // Draw enemies holding the Hero directly above the Hero
4571
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 for(int32_t i=0; i<guys.Count(); i++)
4572 {
4573 if(((enemy*)guys.spr(i))->type == eeWALK)
4574 if(((eStalfos*)guys.spr(i))->hashero)
4575 guys.spr(i)->draw(dest);
4576 else if(((enemy*)guys.spr(i))->type == eeWALLM)
4577 if(((eWallM*)guys.spr(i))->hashero)
4578 guys.spr(i)->draw(dest);
4579 }
4580 2930 }
4581
2/2
✓ Branch 0 taken 24838 times.
✓ Branch 1 taken 2930 times.
27768 else if(spr == &mblock2) // Draw the moving pushblock
4582 {
4583 2930 mblock2.draw(dest, -1);
4584 2930 do_primitives(dest, SPLAYER_MOVINGBLOCK);
4585 2930 }
4586
2/4
✓ Branch 0 taken 24838 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 24838 times.
24838 else if(enemy* e = dynamic_cast<enemy*>(spr))
4587 {
4588 e->draw(dest);
4589 e->draw2(dest); // used specifically for eGleeok/esGleeok
4590 }
4591 24838 else spr->draw(dest);
4592 30698 ++it;
4593 }
4594
1/2
✓ Branch 0 taken 4675 times.
✗ Branch 1 not taken.
4675 if(do_clip)
4595 clear_clip_rect(dest);
4596 17580 }
4597
4598 11991 static void draw_high_darkness(BITMAP* dest)
4599 {
4600 11991 do_primitives(dest, SPLAYER_DARKROOM_UNDER);
4601 11991 set_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
4602
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
4603 {
4604 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
4605 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
4606 }
4607
4608 11991 color_map = trans_table2;
4609
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
4610 {
4611 draw_trans_sprite(dest, darkscr_bmp, 0, 0);
4612 if(get_qr(qr_NEWDARK_TRANS_STACKING))
4613 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
4614 }
4615 else
4616 {
4617 11991 masked_blit(darkscr_bmp, dest, 0, 0, 0, 0, dest->w, dest->h);
4618 11991 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
4619 }
4620 11991 color_map = trans_table;
4621
4622 11991 set_clip_rect(dest, 0, 0, dest->w, dest->h);
4623 11991 do_primitives(dest, SPLAYER_DARKROOM_OVER);
4624 11991 }
4625
4626 16176044 static void draw_screen_post_passive_subscreen(BITMAP* dest, bool any_dark)
4627 {
4628 16176044 draw_msgstr(6, dest);
4629
4630
1/2
✓ Branch 0 taken 16176044 times.
✗ Branch 1 not taken.
16176044 if (get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
4631 draw_msgstr(6, dest);
4632
4633
6/6
✓ Branch 0 taken 1905831 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 453730 times.
✓ Branch 3 taken 1452101 times.
✓ Branch 4 taken 441739 times.
✓ Branch 5 taken 11991 times.
16176044 if (get_qr(qr_NEW_DARKROOM) && !get_qr(qr_NEWDARK_L6) && any_dark)
4634 11991 draw_high_darkness(dest);
4635
4636 16176044 _do_current_ffc_layer(dest, 7);
4637 16176044 draw_msgstr(7, dest);
4638 16176044 }
4639
4640 // Draws to framebuf.
4641 //
4642 // But if drawPassiveSubscreenSeparate is true: framebuf_no_passive_subscreen will also contain all
4643 // draws excluding the passive subscreen.
4644 16133788 void draw_screen(bool showhero, bool runGeneric, bool drawPassiveSubscreenSeparate)
4645 {
4646 16133788 bool classic_draw = get_qr(qr_CLASSIC_DRAWING_ORDER);
4647 16133788 clear_info_bmp();
4648
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16133788 times.
16133788 if((GameFlags & (GAMEFLAG_SCRIPTMENU_ACTIVE|GAMEFLAG_F6SCRIPT_ACTIVE))!=0)
4649 {
4650 FFCore.doScriptMenuDraws();
4651 return;
4652 }
4653
4654
2/2
✓ Branch 0 taken 613773 times.
✓ Branch 1 taken 15520015 times.
16133788 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_PRE_DRAW);
4655
4656 16133788 BITMAP* dest = framebuf;
4657 16133788 clear_bitmap(dest);
4658 16133788 clear_clip_rect(dest);
4659
4660 16133788 int32_t cmby2=0;
4661
4662 // Draw some background layers
4663 16133788 clear_bitmap(scrollbuf);
4664
4665 16133788 auto nearby_screens = get_nearby_screens();
4666
4667
2/2
✓ Branch 0 taken 16130858 times.
✓ Branch 1 taken 2930 times.
16133788 if (!classic_draw)
4668 {
4669
2/2
✓ Branch 0 taken 11720 times.
✓ Branch 1 taken 2930 times.
14650 for (int layer = -7; layer <= -4; ++layer)
4670 {
4671
1/2
✓ Branch 0 taken 11720 times.
✗ Branch 1 not taken.
11720 _do_current_ffc_layer(scrollbuf, layer);
4672
2/4
✓ Branch 0 taken 11720 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11720 times.
11720 if (script_drawing_commands.is_dirty(layer))
4673 do_primitives(scrollbuf, layer);
4674 11720 }
4675 2930 }
4676
4677 // Handle layer 2/3 possibly being background layers.
4678
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16130858 times.
16133788 if (classic_draw) // weird ordering (-3 > -2)
4679 {
4680
1/2
✓ Branch 0 taken 16130858 times.
✗ Branch 1 not taken.
32398034 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4681 16267176 mapscr* base_scr = screen_handles[0].base_scr;
4682
2/2
✓ Branch 0 taken 16125055 times.
✓ Branch 1 taken 142121 times.
16267176 if (XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4683 142121 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4684 16267176 });
4685
4686 16130858 bool l2bg = XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG);
4687
2/2
✓ Branch 0 taken 142121 times.
✓ Branch 1 taken 15988737 times.
16130858 if (l2bg)
4688 {
4689
1/2
✓ Branch 0 taken 142121 times.
✗ Branch 1 not taken.
142121 do_layer_primitives(scrollbuf, 2);
4690
1/2
✓ Branch 0 taken 142121 times.
✗ Branch 1 not taken.
142121 particles.draw(scrollbuf, true, 2);
4691 142121 }
4692
1/2
✓ Branch 0 taken 16130858 times.
✗ Branch 1 not taken.
16130858 _do_current_ffc_layer(scrollbuf, -2);
4693
2/2
✓ Branch 0 taken 142121 times.
✓ Branch 1 taken 15988737 times.
16130858 if (l2bg)
4694
1/2
✓ Branch 0 taken 142121 times.
✗ Branch 1 not taken.
142121 draw_msgstr(2, scrollbuf);
4695 16130858 }
4696
4697
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
32403894 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4698 16270106 mapscr* base_scr = screen_handles[0].base_scr;
4699
2/2
✓ Branch 0 taken 16035542 times.
✓ Branch 1 taken 234564 times.
16270106 if (XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4700 234564 do_layer(scrollbuf, 0, screen_handles[3], offx, offy);
4701 16270106 });
4702
4703
2/2
✓ Branch 0 taken 234564 times.
✓ Branch 1 taken 15899224 times.
16133788 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4704 {
4705
1/2
✓ Branch 0 taken 234564 times.
✗ Branch 1 not taken.
234564 do_layer_primitives(scrollbuf, 3);
4706
1/2
✓ Branch 0 taken 234564 times.
✗ Branch 1 not taken.
234564 particles.draw(scrollbuf, true, 3);
4707 234564 }
4708
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 _do_current_ffc_layer(scrollbuf, -3);
4709
2/2
✓ Branch 0 taken 234564 times.
✓ Branch 1 taken 15899224 times.
16133788 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4710
1/2
✓ Branch 0 taken 234564 times.
✗ Branch 1 not taken.
234564 draw_msgstr(3, scrollbuf);
4711
4712
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16130858 times.
16133788 if (!classic_draw)
4713 {
4714
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 do_primitives(scrollbuf, -3);
4715 // Actually use proper ordering (-3 < -2)
4716
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
5860 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4717 2930 mapscr* base_scr = screen_handles[0].base_scr;
4718
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 if (XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4719 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4720 2930 });
4721
4722 2930 bool l2bg = XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG);
4723
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 if (l2bg)
4724 {
4725 do_layer_primitives(scrollbuf, 2);
4726 particles.draw(scrollbuf, true, 2);
4727 }
4728
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 _do_current_ffc_layer(scrollbuf, -2);
4729
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 if (l2bg)
4730 draw_msgstr(2, scrollbuf);
4731
4732
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 do_primitives(scrollbuf, -2);
4733
4734
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 _do_current_ffc_layer(scrollbuf, -1);
4735
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 do_primitives(scrollbuf, -1);
4736 2930 }
4737
4738 // Draw the main combo screens ("layer 0").
4739
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
32403894 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4740 16270106 mapscr* base_scr = screen_handles[0].base_scr;
4741
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16270106 times.
16270106 if (lenscheck(base_scr, 0))
4742 {
4743 16270106 putscr(base_scr, scrollbuf, offx, offy + playing_field_offset);
4744 16270106 }
4745 16270106 });
4746
4747
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16133788 times.
16133788 if (lenscheck(hero_scr, 0))
4748 {
4749
2/2
✓ Branch 0 taken 466467 times.
✓ Branch 1 taken 15667321 times.
16133788 if(!get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4750
3/4
✓ Branch 0 taken 466467 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4136 times.
✓ Branch 3 taken 462331 times.
470603 if(mblock2.draw(scrollbuf,0))
4751
1/2
✓ Branch 0 taken 4136 times.
✗ Branch 1 not taken.
4136 do_primitives(scrollbuf, SPLAYER_MOVINGBLOCK);
4752 16133788 }
4753
4754 // Lens hints, then primitives, then particles.
4755
6/10
✓ Branch 0 taken 16123759 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 16123759 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 16123759 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 5876 times.
✓ Branch 9 taken 4153 times.
16133788 if((lensclk || (get_debug() && zc_getkey(KEY_L))) && !get_qr(qr_OLDLENSORDER))
4756 {
4757
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 draw_lens_under(scrollbuf, false);
4758
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4759 5876 }
4760
4761
2/4
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16133788 times.
✗ Branch 3 not taken.
16133788 if(show_layers[0] && lenscheck(hero_scr,0))
4762
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 do_primitives(scrollbuf, 0);
4763
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 particles.draw(scrollbuf, true, 0);
4764
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 _do_current_ffc_layer(scrollbuf, 0);
4765
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 draw_msgstr(0, scrollbuf);
4766
4767
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 set_draw_screen_clip(scrollbuf);
4768
4769 16133788 bool hero_draw_done = false;
4770
4/6
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16099036 times.
✓ Branch 3 taken 34752 times.
✓ Branch 4 taken 16099036 times.
✗ Branch 5 not taken.
16133788 bool is_cave_walking = ((Hero.getAction()==climbcovertop)||(Hero.getAction()==climbcoverbottom));
4771
2/2
✓ Branch 0 taken 343259 times.
✓ Branch 1 taken 15790529 times.
16133788 if(!(get_qr(qr_LAYER12UNDERCAVE)))
4772 {
4773
4/4
✓ Branch 0 taken 15788650 times.
✓ Branch 1 taken 1879 times.
✓ Branch 2 taken 88384 times.
✓ Branch 3 taken 15700266 times.
15790529 if(showhero && is_cave_walking)
4774 {
4775 88384 hero_draw_done = true;
4776
3/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53632 times.
✓ Branch 3 taken 34752 times.
88384 if(Hero.getAction()==climbcovertop)
4777 {
4778 34752 cmby2=16;
4779 34752 }
4780
2/4
✓ Branch 0 taken 53632 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53632 times.
53632 else if(Hero.getAction()==climbcoverbottom)
4781 {
4782 53632 cmby2=-16;
4783 53632 }
4784
4785
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw2(scrollbuf,true);
4786
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 Hero.draw(scrollbuf);
4787
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw(scrollbuf,true);
4788
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccx = (int32_t)Hero.getClimbCoverX();
4789
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccy = (int32_t)Hero.getClimbCoverY();
4790
4791
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4792
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4793
4794
4/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✓ Branch 5 taken 73152 times.
88384 if(int32_t(Hero.getX())&15)
4795 {
4796
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4797
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4798 15232 }
4799 88384 }
4800 15790529 }
4801
4802
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 16133788 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
16133788 if (get_qr(qr_HERO_DIVE_UNDER_LAYER_1) && Hero.isDiving())
4803 {
4804 Hero.draw_under(scrollbuf);
4805 decorations.draw2(scrollbuf,true);
4806 Hero.draw(scrollbuf);
4807 decorations.draw(scrollbuf,true);
4808 hero_draw_done = true;
4809 }
4810
4811
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
32403894 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4812 16270106 do_layer(scrollbuf, 0, screen_handles[1], offx, offy); // LAYER 1
4813 16270106 });
4814
4815
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 do_layer_primitives(scrollbuf, 1);
4816
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 particles.draw(scrollbuf, true, 1);
4817
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 _do_current_ffc_layer(scrollbuf, 1);
4818
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 draw_msgstr(1, scrollbuf);
4819
4820 // Handle layer 2 NOT being used as background layers.
4821
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
32403894 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4822 16270106 mapscr* base_scr = screen_handles[0].base_scr;
4823
2/2
✓ Branch 0 taken 142121 times.
✓ Branch 1 taken 16127985 times.
16270106 if (!XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4824 16127985 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4825 16270106 });
4826
4827
2/2
✓ Branch 0 taken 15991667 times.
✓ Branch 1 taken 142121 times.
16133788 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4828 {
4829
1/2
✓ Branch 0 taken 15991667 times.
✗ Branch 1 not taken.
15991667 do_layer_primitives(scrollbuf, 2);
4830
1/2
✓ Branch 0 taken 15991667 times.
✗ Branch 1 not taken.
15991667 particles.draw(scrollbuf, true, 2);
4831 15991667 }
4832
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 _do_current_ffc_layer(scrollbuf, 2);
4833
2/2
✓ Branch 0 taken 15991667 times.
✓ Branch 1 taken 142121 times.
16133788 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4834
1/2
✓ Branch 0 taken 15991667 times.
✗ Branch 1 not taken.
15991667 draw_msgstr(2, scrollbuf);
4835
4836
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 do_primitives(scrollbuf, SPLAYER_FFC_DRAW);
4837
4838
2/2
✓ Branch 0 taken 15790529 times.
✓ Branch 1 taken 343259 times.
16133788 if(get_qr(qr_LAYER12UNDERCAVE))
4839 {
4840
2/4
✓ Branch 0 taken 343259 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 343259 times.
343259 if(showhero && is_cave_walking)
4841 {
4842 hero_draw_done = true;
4843 if(Hero.getAction()==climbcovertop)
4844 {
4845 cmby2=16;
4846 }
4847 else if(Hero.getAction()==climbcoverbottom)
4848 {
4849 cmby2=-16;
4850 }
4851
4852 decorations.draw2(scrollbuf,true);
4853 Hero.draw(scrollbuf);
4854 decorations.draw(scrollbuf,true);
4855 int32_t ccx = (int32_t)(Hero.getClimbCoverX());
4856 int32_t ccy = (int32_t)(Hero.getClimbCoverY());
4857
4858 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4859 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4860
4861 if(int32_t(Hero.getX())&15)
4862 {
4863 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4864 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4865 }
4866 }
4867 343259 }
4868
4869
2/2
✓ Branch 0 taken 466467 times.
✓ Branch 1 taken 15667321 times.
16133788 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4870 {
4871
1/2
✓ Branch 0 taken 15667321 times.
✗ Branch 1 not taken.
31470960 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4872 15803639 do_layer(scrollbuf, -2, screen_handles[0], offx, offy); // push blocks!
4873
2/2
✓ Branch 0 taken 14478915 times.
✓ Branch 1 taken 1324724 times.
15803639 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
4874 {
4875 1324724 do_layer(scrollbuf, -2, screen_handles[1], offx, offy); // push blocks!
4876 1324724 do_layer(scrollbuf, -2, screen_handles[2], offx, offy); // push blocks!
4877 1324724 }
4878 15803639 });
4879
4880
1/2
✓ Branch 0 taken 15667321 times.
✗ Branch 1 not taken.
15667321 do_primitives(scrollbuf, SPLAYER_PUSHBLOCK);
4881 15667321 }
4882
4883 // Show walkflags cheat
4884
2/4
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 16133788 times.
16133788 if (show_walkflags || show_effectflags)
4885 {
4886 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4887 do_walkflags(screen_handles, offx, offy);
4888 do_effectflags(screen_handles[0].base_scr, offx, offy);
4889 });
4890
4891 do_walkflags(0, 0);
4892 }
4893
4894
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 putscrdoors(nearby_screens, scrollbuf, 0, playing_field_offset);
4895
4896 // Lens hints, doors etc.
4897
4/8
✓ Branch 0 taken 16123759 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 16123759 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 16123759 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
16133788 if(lensclk || (get_debug() && zc_getkey(KEY_L)))
4898 {
4899
2/2
✓ Branch 0 taken 4153 times.
✓ Branch 1 taken 5876 times.
10029 if(get_qr(qr_OLDLENSORDER))
4900 {
4901
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 draw_lens_under(scrollbuf, false);
4902
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4903 4153 }
4904
4905
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 draw_lens_under(scrollbuf, true);
4906
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_2);
4907 10029 }
4908
4909 // Blit those layers onto dest (framebuf)
4910
4911
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 set_draw_screen_clip(dest);
4912
4913
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 blit(scrollbuf, dest, 0, 0, 0, 0, 256, 232);
4914
4915 // After this point, scrollbuf is no longer drawn to - so things like dosubscr have access to a "partially rendered" frame.
4916 // I think only used for COOLSCROLL==0? Seems like a silly feature...
4917
4918 // Draw the subscreen, without clipping
4919
2/2
✓ Branch 0 taken 9251384 times.
✓ Branch 1 taken 6882404 times.
16133788 if(!get_qr(qr_SUBSCREENOVERSPRITES))
4920 {
4921 9251384 bool dotime = false;
4922
4/6
✓ Branch 0 taken 9251384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3412853 times.
✓ Branch 3 taken 5838531 times.
✓ Branch 4 taken 3412853 times.
✗ Branch 5 not taken.
9251384 if (replay_version_check(22)) dotime = game->should_show_time();
4923
1/2
✓ Branch 0 taken 9251384 times.
✗ Branch 1 not taken.
9251384 put_passive_subscr(dest, 0, 0, dotime, sspUP);
4924 9251384 }
4925
4926 // Draw some sprites onto dest
4927
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 set_clip_rect(dest,0,0,256,232);
4928
4929
2/2
✓ Branch 0 taken 99496 times.
✓ Branch 1 taken 16034292 times.
16133788 if(!(pricesdisplaybuf->clip))
4930 {
4931
1/2
✓ Branch 0 taken 99496 times.
✗ Branch 1 not taken.
99496 masked_blit(pricesdisplaybuf,dest,0,0,0,playing_field_offset,256,176);
4932 99496 }
4933
4934
5/6
✓ Branch 0 taken 16088162 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 16081834 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
16133788 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4935 add_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
4936
4937
4/4
✓ Branch 0 taken 16131909 times.
✓ Branch 1 taken 1879 times.
✓ Branch 2 taken 16043525 times.
✓ Branch 3 taken 88384 times.
16133788 if(showhero && !hero_draw_done)
4938 {
4939
1/2
✓ Branch 0 taken 16043525 times.
✗ Branch 1 not taken.
16043525 Hero.draw_under(dest);
4940
4941
3/4
✓ Branch 0 taken 16043525 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 141385 times.
✓ Branch 3 taken 15902140 times.
16043525 if(Hero.isSwimming())
4942 {
4943
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw2(dest,true);
4944
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 Hero.draw(dest);
4945
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw(dest,true);
4946 141385 hero_draw_done = true;
4947 141385 }
4948 16043525 }
4949
4950 16133788 set<sprite*, SpriteSorter> sorted_sprites;
4951 16133788 vector<sprite*> temp_sprites;
4952 16133788 std::function<bool(sprite&)> add_sprite = [&](sprite& spr)
4953 {
4954 sorted_sprites.insert(&spr);
4955 return false;
4956 };
4957
4958
2/2
✓ Branch 0 taken 16130858 times.
✓ Branch 1 taken 2930 times.
16133788 if (classic_draw)
4959 {
4960
2/2
✓ Branch 0 taken 26095 times.
✓ Branch 1 taken 16104763 times.
16130858 if(drawguys)
4961 {
4962
4/4
✓ Branch 0 taken 1982674 times.
✓ Branch 1 taken 14122089 times.
✓ Branch 2 taken 991089 times.
✓ Branch 3 taken 991585 times.
16104763 if(get_qr(qr_NOFLICKER) || (frame&1))
4963 {
4964 // Just clips sprites if in a repeating, smooth maze.
4965
2/2
✓ Branch 0 taken 15103964 times.
✓ Branch 1 taken 9214 times.
15113178 bool do_clip = maze_state.active && maze_state.loopy;
4966
4967
1/2
✓ Branch 0 taken 15113178 times.
✗ Branch 1 not taken.
15113178 if(!get_qr(qr_OLD_WEAPON_DRAW_ANIMATE_TIMING))
4968 {
4969 if (do_clip)
4970 {
4971 Ewpns.drawshadow_smooth_maze(dest,get_qr(qr_TRANSSHADOWS));
4972 Lwpns.drawshadow_smooth_maze(dest,get_qr(qr_TRANSSHADOWS));
4973 }
4974 else
4975 {
4976 Ewpns.drawshadow(dest,get_qr(qr_TRANSSHADOWS),true);
4977 Lwpns.drawshadow(dest,get_qr(qr_TRANSSHADOWS),true);
4978 }
4979 }
4980
3/4
✓ Branch 0 taken 24918252 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9805074 times.
✓ Branch 3 taken 15113178 times.
24918252 for(int32_t i=0; i<Ewpns.Count(); i++)
4981 {
4982
3/4
✓ Branch 0 taken 9805074 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 250942 times.
✓ Branch 3 taken 9554132 times.
9805074 if(((weapon *)Ewpns.spr(i))->behind)
4983
2/4
✓ Branch 0 taken 250942 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 250942 times.
✗ Branch 3 not taken.
250942 Ewpns.spr(i)->draw(dest);
4984 9805074 }
4985
1/2
✓ Branch 0 taken 15113178 times.
✗ Branch 1 not taken.
15113178 do_primitives(dest, SPLAYER_EWEAP_BEHIND_DRAW);
4986
4987
3/4
✓ Branch 0 taken 21297169 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6183991 times.
✓ Branch 3 taken 15113178 times.
21297169 for(int32_t i=0; i<Lwpns.Count(); i++)
4988 {
4989
3/4
✓ Branch 0 taken 6183991 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1206996 times.
✓ Branch 3 taken 4976995 times.
6183991 if(((weapon *)Lwpns.spr(i))->behind)
4990
2/4
✓ Branch 0 taken 1206996 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1206996 times.
✗ Branch 3 not taken.
1206996 Lwpns.spr(i)->draw(dest);
4991 6183991 }
4992
1/2
✓ Branch 0 taken 15113178 times.
✗ Branch 1 not taken.
15113178 do_primitives(dest, SPLAYER_LWEAP_BEHIND_DRAW);
4993
4994
6/6
✓ Branch 0 taken 10376314 times.
✓ Branch 1 taken 4736864 times.
✓ Branch 2 taken 1348300 times.
✓ Branch 3 taken 9028014 times.
✓ Branch 4 taken 674011 times.
✓ Branch 5 taken 674289 times.
15113178 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4995 {
4996
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 9698367 times.
9702025 if (do_clip)
4997
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.drawshadow_smooth_maze(dest,get_qr(qr_TRANSSHADOWS)!=0);
4998 else
4999
1/2
✓ Branch 0 taken 9698367 times.
✗ Branch 1 not taken.
9698367 guys.drawshadow(dest,get_qr(qr_TRANSSHADOWS)!=0,true);
5000 9702025 }
5001
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15109520 times.
15113178 if (do_clip)
5002
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.draw_smooth_maze(dest);
5003 else
5004
1/2
✓ Branch 0 taken 15109520 times.
✗ Branch 1 not taken.
15109520 guys.draw(dest,true);
5005
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15109520 times.
15113178 if (do_clip)
5006 {
5007 3658 int maze_screen = maze_state.scr->screen;
5008
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
5009
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(dest, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
5010 3658 }
5011
1/2
✓ Branch 0 taken 15113178 times.
✗ Branch 1 not taken.
15113178 do_primitives(dest, SPLAYER_NPC_DRAW);
5012
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15109520 times.
15113178 if (do_clip)
5013
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(dest);
5014
5015
1/2
✓ Branch 0 taken 15113178 times.
✗ Branch 1 not taken.
15113178 chainlinks.draw(dest,true);
5016
1/2
✓ Branch 0 taken 15113178 times.
✗ Branch 1 not taken.
15113178 do_primitives(dest, SPLAYER_CHAINLINK_DRAW);
5017 //Lwpns.draw(dest,true);
5018
5019
3/4
✓ Branch 0 taken 24918252 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9805074 times.
✓ Branch 3 taken 15113178 times.
24918252 for(int32_t i=0; i<Ewpns.Count(); i++)
5020 {
5021
3/4
✓ Branch 0 taken 9805074 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9554132 times.
✓ Branch 3 taken 250942 times.
9805074 if(!((weapon *)Ewpns.spr(i))->behind)
5022
2/4
✓ Branch 0 taken 9554132 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9554132 times.
✗ Branch 3 not taken.
9554132 Ewpns.spr(i)->draw(dest);
5023 9805074 }
5024
1/2
✓ Branch 0 taken 15113178 times.
✗ Branch 1 not taken.
15113178 do_primitives(dest, SPLAYER_EWEAP_FRONT_DRAW);
5025
5026
3/4
✓ Branch 0 taken 21297169 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6183991 times.
✓ Branch 3 taken 15113178 times.
21297169 for(int32_t i=0; i<Lwpns.Count(); i++)
5027 {
5028
3/4
✓ Branch 0 taken 6183991 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4976995 times.
✓ Branch 3 taken 1206996 times.
6183991 if(!((weapon *)Lwpns.spr(i))->behind)
5029
2/4
✓ Branch 0 taken 4976995 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4976995 times.
✗ Branch 3 not taken.
4976995 Lwpns.spr(i)->draw(dest);
5030 6183991 }
5031
1/2
✓ Branch 0 taken 15113178 times.
✗ Branch 1 not taken.
15113178 do_primitives(dest, SPLAYER_LWEAP_FRONT_DRAW);
5032
5033
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15109520 times.
15113178 if (do_clip)
5034
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 items.draw_smooth_maze(dest);
5035 else
5036
1/2
✓ Branch 0 taken 15109520 times.
✗ Branch 1 not taken.
15109520 items.draw(dest,true);
5037
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15109520 times.
15113178 if (do_clip)
5038 {
5039 3658 int maze_screen = maze_state.scr->screen;
5040
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
5041
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(dest, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
5042 3658 }
5043
1/2
✓ Branch 0 taken 15113178 times.
✗ Branch 1 not taken.
15113178 do_primitives(dest, SPLAYER_ITEMSPRITE_DRAW);
5044
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15109520 times.
15113178 if (do_clip)
5045
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(dest);
5046 15113178 }
5047 else
5048 {
5049
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
5050 {
5051
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✓ Branch 3 taken 496727 times.
505372 if(((weapon *)Ewpns.spr(i))->behind)
5052
2/4
✓ Branch 0 taken 8645 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✗ Branch 3 not taken.
8645 Ewpns.spr(i)->draw(dest);
5053 505372 }
5054
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_EWEAP_BEHIND_DRAW);
5055
5056
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
5057 {
5058
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 231146 times.
231146 if(((weapon *)Lwpns.spr(i))->behind)
5059 Lwpns.spr(i)->draw(dest);
5060 231146 }
5061
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_LWEAP_BEHIND_DRAW);
5062
5063
3/4
✓ Branch 0 taken 228620 times.
✓ Branch 1 taken 762965 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 228620 times.
991585 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
5064 {
5065
1/2
✓ Branch 0 taken 228620 times.
✗ Branch 1 not taken.
228620 guys.drawshadow(dest,get_qr(qr_TRANSSHADOWS)!=0,true);
5066 228620 }
5067
5068
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 items.draw(dest,false);
5069
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_ITEMSPRITE_DRAW);
5070
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 chainlinks.draw(dest,false);
5071
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_CHAINLINK_DRAW);
5072 //Lwpns.draw(dest,false);
5073
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 guys.draw(dest,false);
5074
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_NPC_DRAW);
5075
5076
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
5077 {
5078
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✓ Branch 3 taken 8645 times.
505372 if(!((weapon *)Ewpns.spr(i))->behind)
5079 {
5080
2/4
✓ Branch 0 taken 496727 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✗ Branch 3 not taken.
496727 Ewpns.spr(i)->draw(dest);
5081 496727 }
5082 505372 }
5083
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_EWEAP_FRONT_DRAW);
5084
5085
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
5086 {
5087
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 if(!((weapon *)Lwpns.spr(i))->behind)
5088 {
5089
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 Lwpns.spr(i)->draw(dest);
5090 231146 }
5091 231146 }
5092
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_LWEAP_FRONT_DRAW);
5093 }
5094
5095
1/2
✓ Branch 0 taken 16104763 times.
✗ Branch 1 not taken.
16104763 guys.draw2(dest,true);
5096 16104763 }
5097
5098
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16130858 times.
16130858 if(mirror_portal.destdmap > -1)
5099 mirror_portal.draw(dest);
5100
1/2
✓ Branch 0 taken 16130858 times.
✗ Branch 1 not taken.
16130858 portals.draw(dest,true);
5101
5102
4/4
✓ Branch 0 taken 16128979 times.
✓ Branch 1 taken 1879 times.
✓ Branch 2 taken 88384 times.
✓ Branch 3 taken 16040595 times.
16130858 if(showhero && !is_cave_walking)
5103 {
5104
2/2
✓ Branch 0 taken 15580545 times.
✓ Branch 1 taken 460050 times.
16040595 if(get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
5105 {
5106
1/2
✓ Branch 0 taken 15580545 times.
✗ Branch 1 not taken.
15580545 mblock2.draw(dest,-1);
5107
1/2
✓ Branch 0 taken 15580545 times.
✗ Branch 1 not taken.
15580545 do_primitives(dest, SPLAYER_MOVINGBLOCK);
5108 15580545 }
5109
2/2
✓ Branch 0 taken 15899210 times.
✓ Branch 1 taken 141385 times.
16040595 if(!hero_draw_done)
5110 {
5111
8/12
✓ Branch 0 taken 15899210 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15899210 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15880040 times.
✓ Branch 5 taken 19170 times.
✓ Branch 6 taken 15880040 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15880040 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1370 times.
✓ Branch 11 taken 15897840 times.
15899210 if((Hero.getZ()>0 || Hero.getFakeZ()>0) &&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
5112 {
5113
2/2
✓ Branch 0 taken 18485 times.
✓ Branch 1 taken 15880725 times.
15899210 Hero.drawshadow(dest,get_qr(qr_TRANSSHADOWS)!=0);
5114 18485 }
5115
5116
6/8
✓ Branch 0 taken 15899210 times.
✓ Branch 1 taken 15880725 times.
✓ Branch 2 taken 15899210 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15899210 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15885146 times.
✓ Branch 7 taken 14064 times.
18485 if(Hero.getZ() <= (zfix)zinit.jump_hero_layer_threshold)
5117 {
5118
1/2
✓ Branch 0 taken 15885146 times.
✗ Branch 1 not taken.
15885146 decorations.draw2(dest,true);
5119
1/2
✓ Branch 0 taken 15885146 times.
✗ Branch 1 not taken.
15885146 Hero.draw(dest);
5120
1/2
✓ Branch 0 taken 15885146 times.
✗ Branch 1 not taken.
15885146 decorations.draw(dest,true);
5121 15885146 hero_draw_done = true;
5122 15885146 }
5123 15899210 }
5124 16040595 }
5125
5126
3/4
✓ Branch 0 taken 56548426 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40417568 times.
✓ Branch 3 taken 16130858 times.
56548426 for(int32_t i=0; i<guys.Count(); i++)
5127 {
5128
3/4
✓ Branch 0 taken 40417568 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16520322 times.
✓ Branch 3 taken 23897246 times.
40417568 if(((enemy*)guys.spr(i))->type == eeWALK)
5129 {
5130
3/4
✓ Branch 0 taken 16520322 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7965 times.
✓ Branch 3 taken 16512357 times.
16520322 if(((eStalfos*)guys.spr(i))->hashero)
5131 {
5132
2/4
✓ Branch 0 taken 7965 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7965 times.
✗ Branch 3 not taken.
7965 guys.spr(i)->draw(dest);
5133 7965 }
5134 16520322 }
5135
5136
3/4
✓ Branch 0 taken 40417568 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 507162 times.
✓ Branch 3 taken 39910406 times.
40417568 if(((enemy*)guys.spr(i))->type == eeWALLM)
5137 {
5138
3/4
✓ Branch 0 taken 507162 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✓ Branch 3 taken 505833 times.
507162 if(((eWallM*)guys.spr(i))->hashero)
5139 {
5140
2/4
✓ Branch 0 taken 1329 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✗ Branch 3 not taken.
1329 guys.spr(i)->draw(dest);
5141 1329 }
5142 507162 }
5143
5144
11/20
✓ Branch 0 taken 40417568 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40417568 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 40417568 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 40417568 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 40417568 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 40417568 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 40417568 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 40417568 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 40417568 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1523506 times.
✓ Branch 19 taken 38894062 times.
40417568 if(guys.spr(i)->z+guys.spr(i)->fakez > Hero.getZ()+Hero.getFakeZ())
5145 {
5146 //Jumping enemies in front of Hero.
5147
2/4
✓ Branch 0 taken 1523506 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1523506 times.
✗ Branch 3 not taken.
1523506 guys.spr(i)->draw(dest);
5148 1523506 }
5149
1/2
✓ Branch 0 taken 40417568 times.
✗ Branch 1 not taken.
40417568 do_primitives(dest, SPLAYER_NPC_ABOVEPLAYER_DRAW);
5150 40417568 }
5151 16130858 }
5152 else
5153 {
5154
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 if(drawguys)
5155 {
5156
2/4
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
2930 chainlinks.forEach(add_sprite);
5157
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
5860 bool show_enemy_shadows = (get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1));
5158 25837 auto add_spr_shadow = [&](sprite& spr)
5159 {
5160 22907 sorted_sprites.insert(&spr);
5161
3/4
✓ Branch 0 taken 1291 times.
✓ Branch 1 taken 21616 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1291 times.
22907 if(spr.total_z() > 0 && spr.can_drawshadow())
5162 {
5163
1/2
✓ Branch 0 taken 1291 times.
✗ Branch 1 not taken.
1291 tempsprite_shadow* shadow = new tempsprite_shadow(&spr);
5164 1291 sorted_sprites.insert(shadow);
5165 1291 temp_sprites.push_back(shadow);
5166 1291 }
5167 22907 return false;
5168 };
5169
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 Lwpns.forEach(add_spr_shadow);
5170
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 Ewpns.forEach(add_spr_shadow);
5171
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 items.forEach(add_spr_shadow);
5172
4/14
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2930 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2930 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 2930 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
2930 guys.forEach(show_enemy_shadows ? add_spr_shadow : add_sprite);
5173 2930 }
5174
2/4
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
2930 if(showhero && !hero_draw_done)
5175 {
5176
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 sorted_sprites.insert(&Hero);
5177
9/14
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2290 times.
✓ Branch 5 taken 640 times.
✓ Branch 6 taken 2290 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2290 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2930 times.
✓ Branch 12 taken 2290 times.
✓ Branch 13 taken 2290 times.
2930 if((Hero.getZ()>0 || Hero.getFakeZ()>0) &&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
5178 {
5179
3/4
✓ Branch 0 taken 640 times.
✓ Branch 1 taken 4580 times.
✓ Branch 2 taken 640 times.
✗ Branch 3 not taken.
5220 tempsprite_shadow* shadow = new tempsprite_shadow(&Hero);
5180
1/2
✓ Branch 0 taken 640 times.
✗ Branch 1 not taken.
640 sorted_sprites.insert(shadow);
5181
1/2
✓ Branch 0 taken 640 times.
✗ Branch 1 not taken.
640 temp_sprites.push_back(shadow);
5182 640 }
5183 2930 }
5184
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 if(mirror_portal.destdmap > -1)
5185 sorted_sprites.insert(&mirror_portal);
5186
2/4
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
2930 portals.forEach(add_sprite);
5187
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 if(get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
5188
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 sorted_sprites.insert(&mblock2);
5189 }
5190 16133788 auto sprite_it = sorted_sprites.begin();
5191
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16130858 times.
16133788 if (!classic_draw)
5192
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_GROUND]);
5193
5194 // Draw some layers onto dest
5195
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 set_draw_screen_clip(dest);
5196
5/6
✓ Branch 0 taken 16088162 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 16081834 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
16133788 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
5197 add_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
5198
5199 // Handle layer 3 NOT being used as background layers.
5200
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
32403894 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5201 16270106 mapscr* base_scr = screen_handles[0].base_scr;
5202
2/2
✓ Branch 0 taken 234564 times.
✓ Branch 1 taken 16035542 times.
16270106 if (!XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
5203 16035542 do_layer(dest, 0, screen_handles[3], offx, offy);
5204 16270106 });
5205
5206
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16130858 times.
16133788 if (!classic_draw)
5207
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_3]);
5208
5209
2/2
✓ Branch 0 taken 15899224 times.
✓ Branch 1 taken 234564 times.
16133788 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
5210 {
5211
1/2
✓ Branch 0 taken 15899224 times.
✗ Branch 1 not taken.
15899224 do_layer_primitives(dest, 3);
5212
1/2
✓ Branch 0 taken 15899224 times.
✗ Branch 1 not taken.
15899224 particles.draw(dest, true, 3);
5213 15899224 }
5214
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 _do_current_ffc_layer(dest, 3);
5215
2/2
✓ Branch 0 taken 15899224 times.
✓ Branch 1 taken 234564 times.
16133788 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
5216
1/2
✓ Branch 0 taken 15899224 times.
✗ Branch 1 not taken.
15899224 draw_msgstr(3);
5217
5218
5219
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
32403894 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5220 16270106 do_layer(dest, 0, screen_handles[4], offx, offy);
5221 16270106 });
5222
5223
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16130858 times.
16133788 if (!classic_draw)
5224
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_4]);
5225
5226
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 do_layer_primitives(dest, 4);
5227
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 particles.draw(dest, true, 4);
5228
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 _do_current_ffc_layer(dest, 4);
5229
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 draw_msgstr(4);
5230
5231
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
32403894 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5232 16270106 do_layer(dest, -1, screen_handles[0], offx, offy);
5233
2/2
✓ Branch 0 taken 14402748 times.
✓ Branch 1 taken 1867358 times.
16270106 if (get_qr(qr_OVERHEAD_COMBOS_L1_L2))
5234 {
5235 1867358 do_layer(dest, -1, screen_handles[1], offx, offy);
5236 1867358 do_layer(dest, -1, screen_handles[2], offx, offy);
5237 1867358 }
5238 16270106 });
5239
5240
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 do_primitives(dest, SPLAYER_OVERHEAD_CMB);
5241
5242 // Draw some flying sprites onto dest
5243
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 clear_clip_rect(dest);
5244
5/6
✓ Branch 0 taken 16088162 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 16081834 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
16133788 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
5245 add_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
5246
5247
2/2
✓ Branch 0 taken 16130858 times.
✓ Branch 1 taken 2930 times.
16133788 if (classic_draw)
5248 {
5249 //Jumping Hero and jumping enemies are drawn on this layer.
5250
5/8
✓ Branch 0 taken 16130858 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16130858 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16130858 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14064 times.
✓ Branch 7 taken 16116794 times.
16130858 if(Hero.getZ() > (zfix)zinit.jump_hero_layer_threshold)
5251 {
5252
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw2(dest,false);
5253
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 Hero.draw(dest);
5254
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 chainlinks.draw(dest,true);
5255
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(dest, SPLAYER_CHAINLINK_DRAW);
5256
5257
3/4
✓ Branch 0 taken 16806 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✓ Branch 3 taken 14064 times.
16806 for(int32_t i=0; i<Lwpns.Count(); i++)
5258 {
5259
9/16
✓ Branch 0 taken 2742 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2742 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2742 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2742 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2742 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2742 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 239 times.
✓ Branch 15 taken 2503 times.
2742 if(Lwpns.spr(i)->z+Lwpns.spr(i)->fakez > (zfix)zinit.jump_hero_layer_threshold)
5260 {
5261
2/4
✓ Branch 0 taken 239 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 239 times.
✗ Branch 3 not taken.
239 Lwpns.spr(i)->draw(dest);
5262 239 }
5263 2742 }
5264
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(dest, SPLAYER_LWEAP_ABOVE_DRAW);
5265
5266
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw(dest,false);
5267 14064 }
5268
5269
5/6
✓ Branch 0 taken 3872989 times.
✓ Branch 1 taken 12257869 times.
✓ Branch 2 taken 44341460 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 32083591 times.
✓ Branch 5 taken 12257869 times.
48214449 if(!get_qr(qr_ENEMIESZAXIS)) for(int32_t i=0; i<guys.Count(); i++)
5270 {
5271
13/22
✓ Branch 0 taken 32083591 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32083591 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 27177493 times.
✓ Branch 5 taken 4906098 times.
✓ Branch 6 taken 27177493 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 27177493 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 27177493 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 27177493 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 27177493 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 27177493 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 27177493 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 6568 times.
✓ Branch 21 taken 27170925 times.
32083591 if((isflier(guys.spr(i)->id)) || (guys.spr(i)->z+guys.spr(i)->fakez) > (zfix)zinit.jump_hero_layer_threshold)
5272 {
5273
2/4
✓ Branch 0 taken 4912666 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4912666 times.
✗ Branch 3 not taken.
4912666 guys.spr(i)->draw(dest);
5274 4912666 }
5275 44341460 }
5276 else
5277 {
5278
3/4
✓ Branch 0 taken 12206966 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8333977 times.
✓ Branch 3 taken 3872989 times.
12206966 for(int32_t i=0; i<guys.Count(); i++)
5279 {
5280
13/22
✓ Branch 0 taken 8333977 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8333977 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6997572 times.
✓ Branch 5 taken 1336405 times.
✓ Branch 6 taken 6997572 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6997572 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6997572 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 6478745 times.
✓ Branch 13 taken 518827 times.
✓ Branch 14 taken 6478745 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 6478745 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 6478745 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 6478745 times.
8333977 if((isflier(guys.spr(i)->id)) || guys.spr(i)->z > 0 || guys.spr(i)->fakez > 0)
5281 {
5282
2/4
✓ Branch 0 taken 1855232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1855232 times.
✗ Branch 3 not taken.
1855232 guys.spr(i)->draw(dest);
5283 1855232 }
5284 8333977 }
5285 }
5286
1/2
✓ Branch 0 taken 16130858 times.
✗ Branch 1 not taken.
16130858 do_primitives(dest, SPLAYER_NPC_AIRBORNE_DRAW);
5287 16130858 }
5288
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 else draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_OVERHEAD]);
5289
5290 // Draw the Moving Fairy above layer 3
5291
3/4
✓ Branch 0 taken 19457924 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3324136 times.
✓ Branch 3 taken 16133788 times.
19457924 for(int32_t i=0; i<items.Count(); i++)
5292
6/8
✓ Branch 0 taken 3324136 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 70250 times.
✓ Branch 3 taken 3253886 times.
✓ Branch 4 taken 70250 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 60536 times.
✓ Branch 7 taken 9714 times.
3384672 if(itemsbuf[items.spr(i)->id].type == itype_fairy && itemsbuf[items.spr(i)->id].misc3)
5293
2/4
✓ Branch 0 taken 60536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 60536 times.
✗ Branch 3 not taken.
60536 items.spr(i)->draw(dest);
5294
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 do_primitives(dest, SPLAYER_FAIRYITEM_DRAW);
5295
5296 // Draw some layers onto dest
5297
5298
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 set_draw_screen_clip(dest);
5299
5300
2/2
✓ Branch 0 taken 16119436 times.
✓ Branch 1 taken 14352 times.
16133788 if (lightbeam_present)
5301 {
5302 14352 color_map = trans_table2;
5303
2/2
✓ Branch 0 taken 13114 times.
✓ Branch 1 taken 1238 times.
14352 if(get_qr(qr_LIGHTBEAM_TRANSPARENT))
5304
1/2
✓ Branch 0 taken 13114 times.
✗ Branch 1 not taken.
13114 draw_trans_sprite(dest, lightbeam_bmp, 0, playing_field_offset);
5305 else
5306
1/2
✓ Branch 0 taken 1238 times.
✗ Branch 1 not taken.
1238 masked_blit(lightbeam_bmp, dest, 0, 0, 0, playing_field_offset, 256, 176);
5307 14352 color_map = trans_table;
5308 14352 }
5309
5310
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
32403894 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5311 16270106 do_layer(dest, 0, screen_handles[5], offx, offy);
5312 16270106 });
5313
5314
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16130858 times.
16133788 if (!classic_draw)
5315
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_5]);
5316
5317
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 do_layer_primitives(dest, 5);
5318
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 particles.draw(dest, true, 5);
5319
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 _do_current_ffc_layer(dest, 5);
5320
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 draw_msgstr(5);
5321
5322
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 _do_current_ffc_layer(dest, -1000); // 'overhead' freeform combos
5323
5324
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 do_primitives(dest, SPLAYER_OVERHEAD_FFC);
5325
5326
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
32403894 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5327 16270106 do_layer(dest, 0, screen_handles[6], offx, offy);
5328 16270106 });
5329
5330
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16130858 times.
16133788 if (!classic_draw)
5331
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, word(-1));
5332
5333
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 do_layer_primitives(dest, 6);
5334
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 particles.draw(dest, true, 6);
5335
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 _do_current_ffc_layer(dest, 6);
5336
5337 16133788 bool any_dark = false;
5338
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
32403894 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5339 16270106 mapscr* base_scr = screen_handles[0].base_scr;
5340 16270106 any_dark |= is_dark(base_scr);
5341 16270106 });
5342
5343 // Handle low drawn darkness
5344
4/4
✓ Branch 0 taken 1863575 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 1516676 times.
✓ Branch 3 taken 346899 times.
16133788 if(get_qr(qr_NEW_DARKROOM) && any_dark)
5345 {
5346
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
700032 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5347 353133 mapscr* base_scr = screen_handles[0].base_scr;
5348 353133 calc_darkroom_combos(base_scr, offx, offy + playing_field_offset);
5349 353133 calc_darkroom_ffcs(base_scr, 0, playing_field_offset);
5350 353133 });
5351
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
346899 if(showhero)
5352
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
346899 Hero.calc_darkroom_hero(0, -playing_field_offset);
5353
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
700032 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5354 353133 mapscr* base_scr = screen_handles[0].base_scr;
5355
2/2
✓ Branch 0 taken 348403 times.
✓ Branch 1 taken 4730 times.
353133 if (!is_dark(base_scr))
5356 {
5357 4730 offy += playing_field_offset;
5358 4730 rectfill(darkscr_bmp, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5359 4730 rectfill(darkscr_bmp_trans, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5360 4730 }
5361 353133 });
5362 346899 }
5363
5364 //Darkroom if under the subscreen
5365
6/6
✓ Branch 0 taken 1863575 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 1409845 times.
✓ Branch 3 taken 453730 times.
✓ Branch 4 taken 334908 times.
✓ Branch 5 taken 1074937 times.
16133788 if(get_qr(qr_NEW_DARKROOM) && get_qr(qr_NEWDARK_L6) && any_dark)
5366 {
5367
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 do_primitives(dest, SPLAYER_DARKROOM_UNDER);
5368
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 set_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
5369
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 334908 times.
334908 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
5370 {
5371 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
5372 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
5373 }
5374
5375 334908 color_map = trans_table2;
5376
2/2
✓ Branch 0 taken 15523 times.
✓ Branch 1 taken 319385 times.
334908 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
5377 {
5378
1/2
✓ Branch 0 taken 15523 times.
✗ Branch 1 not taken.
15523 draw_trans_sprite(dest, darkscr_bmp, 0, 0);
5379
1/2
✓ Branch 0 taken 15523 times.
✗ Branch 1 not taken.
15523 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5380
1/2
✓ Branch 0 taken 15523 times.
✗ Branch 1 not taken.
15523 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
5381 15523 }
5382 else
5383 {
5384
1/2
✓ Branch 0 taken 319385 times.
✗ Branch 1 not taken.
319385 masked_blit(darkscr_bmp, dest, 0, 0, 0, 0, dest->w, dest->h);
5385
1/2
✓ Branch 0 taken 319385 times.
✗ Branch 1 not taken.
319385 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
5386 }
5387 334908 color_map = trans_table;
5388
5389
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 set_clip_rect(dest, 0, 0, dest->w, dest->h);
5390
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 do_primitives(dest, SPLAYER_DARKROOM_OVER);
5391 334908 }
5392
5393
3/6
✓ Branch 0 taken 51954 times.
✓ Branch 1 taken 16081834 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 51954 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
16133788 if (is_in_scrolling_region() && lensclk && !FFCore.system_suspend[susptLENS])
5394 {
5395 draw_lens_over(dest);
5396 --lensclk;
5397 }
5398
5399 // Draw some text on dest
5400
5401
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 set_clip_rect(dest,0,0,256,232);
5402
5403
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 if(!get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5404
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 draw_msgstr(6);
5405
5406 // Draw the subscreen, without clipping
5407
2/2
✓ Branch 0 taken 6882404 times.
✓ Branch 1 taken 9251384 times.
16133788 if(get_qr(qr_SUBSCREENOVERSPRITES))
5408 {
5409
2/2
✓ Branch 0 taken 42256 times.
✓ Branch 1 taken 6840148 times.
6882404 if (drawPassiveSubscreenSeparate)
5410
1/2
✓ Branch 0 taken 42256 times.
✗ Branch 1 not taken.
42256 blit(dest, framebuf_no_passive_subscreen, 0, 0, 0, 0, dest->w, dest->h);
5411
5412
2/4
✓ Branch 0 taken 6882404 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6882404 times.
✗ Branch 3 not taken.
6882404 put_passive_subscr(dest, 0, 0, game->should_show_time(), sspUP);
5413
5414
1/2
✓ Branch 0 taken 6882404 times.
✗ Branch 1 not taken.
6882404 do_primitives(dest, 7);
5415
2/2
✓ Branch 0 taken 42256 times.
✓ Branch 1 taken 6840148 times.
6882404 if (drawPassiveSubscreenSeparate)
5416
1/2
✓ Branch 0 taken 42256 times.
✗ Branch 1 not taken.
42256 do_primitives(framebuf_no_passive_subscreen, 7);
5417 6882404 }
5418
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9251384 times.
9251384 else if (!classic_draw)
5419 do_primitives(dest, 7);
5420
5421
1/2
✓ Branch 0 taken 16133788 times.
✗ Branch 1 not taken.
16133788 draw_screen_post_passive_subscreen(dest, any_dark);
5422
2/2
✓ Branch 0 taken 42256 times.
✓ Branch 1 taken 16091532 times.
16133788 if (drawPassiveSubscreenSeparate)
5423
1/2
✓ Branch 0 taken 42256 times.
✗ Branch 1 not taken.
42256 draw_screen_post_passive_subscreen(framebuf_no_passive_subscreen, any_dark);
5424
5425
2/2
✓ Branch 0 taken 15632242 times.
✓ Branch 1 taken 31766030 times.
16133788 set_clip_rect(scrollbuf, 0, 0, scrollbuf->w, scrollbuf->h);
5426
3/4
✓ Branch 0 taken 15520015 times.
✓ Branch 1 taken 168133 times.
✓ Branch 2 taken 15520015 times.
✗ Branch 3 not taken.
15632242 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_POST_DRAW);
5427
5428
2/2
✓ Branch 0 taken 1931 times.
✓ Branch 1 taken 15688148 times.
15690079 for(sprite* spr : temp_sprites)
5429
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1931 times.
1931 delete spr;
5430 79220208 }
5431
5432 // TODO: separate setting door data and drawing door
5433 28153 void put_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t type, bool redraw, bool even_walls)
5434 {
5435
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28153 times.
28153 if (type > 8) return;
5436
5437 28153 int32_t d=scr->door_combo_set;
5438
5439
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15611 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12542 times.
28153 switch(type)
5440 {
5441 case dt_wall:
5442 case dt_walk:
5443 if(!even_walls)
5444 break;
5445 [[fallthrough]];
5446 case dt_pass:
5447
3/4
✓ Branch 0 taken 1036 times.
✓ Branch 1 taken 11506 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1036 times.
12542 if(!get_qr(qr_REPLACEOPENDOORS) && !even_walls)
5448 1036 break;
5449 [[fallthrough]];
5450 case dt_lock:
5451 case dt_shut:
5452 case dt_boss:
5453 case dt_olck:
5454 case dt_osht:
5455 case dt_obos:
5456 case dt_bomb:
5457
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 7259 times.
✓ Branch 2 taken 6784 times.
✓ Branch 3 taken 6362 times.
✓ Branch 4 taken 6712 times.
27117 switch(side)
5458 {
5459 case up:
5460 7259 scr->data[pos] = DoorComboSets[d].doorcombo_u[type][0];
5461 7259 scr->cset[pos] = DoorComboSets[d].doorcset_u[type][0];
5462 7259 scr->sflag[pos] = 0;
5463 7259 scr->data[pos+1] = DoorComboSets[d].doorcombo_u[type][1];
5464 7259 scr->cset[pos+1] = DoorComboSets[d].doorcset_u[type][1];
5465 7259 scr->sflag[pos+1] = 0;
5466 7259 scr->data[pos+16] = DoorComboSets[d].doorcombo_u[type][2];
5467 7259 scr->cset[pos+16] = DoorComboSets[d].doorcset_u[type][2];
5468 7259 scr->sflag[pos+16] = 0;
5469 7259 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_u[type][3];
5470 7259 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_u[type][3];
5471 7259 scr->sflag[pos+16+1] = 0;
5472
5473
2/2
✓ Branch 0 taken 5435 times.
✓ Branch 1 taken 1824 times.
7259 if(redraw)
5474 {
5475 3648 putcombo(dest,(pos&15)<<4,pos&0xF0,
5476 1824 DoorComboSets[d].doorcombo_u[type][0],
5477 1824 DoorComboSets[d].doorcset_u[type][0]);
5478 3648 putcombo(dest,((pos&15)<<4)+16,pos&0xF0,
5479 1824 DoorComboSets[d].doorcombo_u[type][1],
5480 1824 DoorComboSets[d].doorcset_u[type][1]);
5481 1824 }
5482
5483 7259 break;
5484
5485 case down:
5486 6784 scr->data[pos] = DoorComboSets[d].doorcombo_d[type][0];
5487 6784 scr->cset[pos] = DoorComboSets[d].doorcset_d[type][0];
5488 6784 scr->sflag[pos] = 0;
5489 6784 scr->data[pos+1] = DoorComboSets[d].doorcombo_d[type][1];
5490 6784 scr->cset[pos+1] = DoorComboSets[d].doorcset_d[type][1];
5491 6784 scr->sflag[pos+1] = 0;
5492 6784 scr->data[pos+16] = DoorComboSets[d].doorcombo_d[type][2];
5493 6784 scr->cset[pos+16] = DoorComboSets[d].doorcset_d[type][2];
5494 6784 scr->sflag[pos+16] = 0;
5495 6784 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_d[type][3];
5496 6784 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_d[type][3];
5497 6784 scr->sflag[pos+16+1] = 0;
5498
5499
2/2
✓ Branch 0 taken 5463 times.
✓ Branch 1 taken 1321 times.
6784 if(redraw)
5500 {
5501 2642 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5502 1321 DoorComboSets[d].doorcombo_d[type][2],
5503 1321 DoorComboSets[d].doorcset_d[type][2]);
5504 2642 putcombo(dest,((pos&15)<<4)+16,(pos&0xF0)+16,
5505 1321 DoorComboSets[d].doorcombo_d[type][3],
5506 1321 DoorComboSets[d].doorcset_d[type][3]);
5507 1321 }
5508
5509 6784 break;
5510
5511 case left:
5512 6362 scr->data[pos] = DoorComboSets[d].doorcombo_l[type][0];
5513 6362 scr->cset[pos] = DoorComboSets[d].doorcset_l[type][0];
5514 6362 scr->sflag[pos] = 0;
5515 6362 scr->data[pos+1] = DoorComboSets[d].doorcombo_l[type][1];
5516 6362 scr->cset[pos+1] = DoorComboSets[d].doorcset_l[type][1];
5517 6362 scr->sflag[pos+1] = 0;
5518 6362 scr->data[pos+16] = DoorComboSets[d].doorcombo_l[type][2];
5519 6362 scr->cset[pos+16] = DoorComboSets[d].doorcset_l[type][2];
5520 6362 scr->sflag[pos+16] = 0;
5521 6362 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_l[type][3];
5522 6362 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_l[type][3];
5523 6362 scr->sflag[pos+16+1] = 0;
5524 6362 scr->data[pos+32] = DoorComboSets[d].doorcombo_l[type][4];
5525 6362 scr->cset[pos+32] = DoorComboSets[d].doorcset_l[type][4];
5526 6362 scr->sflag[pos+32] = 0;
5527 6362 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_l[type][5];
5528 6362 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_l[type][5];
5529 6362 scr->sflag[pos+32+1] = 0;
5530
5531
2/2
✓ Branch 0 taken 4873 times.
✓ Branch 1 taken 1489 times.
6362 if(redraw)
5532 {
5533 2978 putcombo(dest,(pos&15)<<4,pos&0xF0,
5534 1489 DoorComboSets[d].doorcombo_l[type][0],
5535 1489 DoorComboSets[d].doorcset_l[type][0]);
5536 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5537 1489 DoorComboSets[d].doorcombo_l[type][2],
5538 1489 DoorComboSets[d].doorcset_l[type][2]);
5539 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5540 1489 DoorComboSets[d].doorcombo_l[type][4],
5541 1489 DoorComboSets[d].doorcset_l[type][4]);
5542 1489 }
5543
5544 6362 break;
5545
5546 case right:
5547 6712 scr->data[pos] = DoorComboSets[d].doorcombo_r[type][0];
5548 6712 scr->cset[pos] = DoorComboSets[d].doorcset_r[type][0];
5549 6712 scr->sflag[pos] = 0;
5550 6712 scr->data[pos+1] = DoorComboSets[d].doorcombo_r[type][1];
5551 6712 scr->cset[pos+1] = DoorComboSets[d].doorcset_r[type][1];
5552 6712 scr->sflag[pos+1] = 0;
5553 6712 scr->data[pos+16] = DoorComboSets[d].doorcombo_r[type][2];
5554 6712 scr->cset[pos+16] = DoorComboSets[d].doorcset_r[type][2];
5555 6712 scr->sflag[pos+16] = 0;
5556 6712 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_r[type][3];
5557 6712 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_r[type][3];
5558 6712 scr->sflag[pos+16+1] = 0;
5559 6712 scr->data[pos+32] = DoorComboSets[d].doorcombo_r[type][4];
5560 6712 scr->cset[pos+32] = DoorComboSets[d].doorcset_r[type][4];
5561 6712 scr->sflag[pos+32] = 0;
5562 6712 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_r[type][5];
5563 6712 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_r[type][5];
5564 6712 scr->sflag[pos+32+1] = 0;
5565
5566
2/2
✓ Branch 0 taken 5058 times.
✓ Branch 1 taken 1654 times.
6712 if(redraw)
5567 {
5568 3308 putcombo(dest,(pos&15)<<4,pos&0xF0,
5569 1654 DoorComboSets[d].doorcombo_r[type][0],
5570 1654 DoorComboSets[d].doorcset_r[type][0]);
5571 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5572 1654 DoorComboSets[d].doorcombo_r[type][2],
5573 1654 DoorComboSets[d].doorcset_r[type][2]);
5574 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5575 1654 DoorComboSets[d].doorcombo_r[type][4],
5576 1654 DoorComboSets[d].doorcset_r[type][4]);
5577 1654 }
5578
5579 6712 break;
5580 }
5581
5582 27117 break;
5583
5584 default:
5585 break;
5586 }
5587 28153 }
5588
5589 706556 static void over_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t offx, int32_t offy)
5590 {
5591 706556 int32_t door_combo_set = scr->door_combo_set;
5592 706556 int32_t x = (pos&15)<<4;
5593 706556 int32_t y = (pos&0xF0);
5594 706556 int32_t d = door_combo_set;
5595 706556 x += offx;
5596 706556 y += offy;
5597
5598
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 161136 times.
✓ Branch 2 taken 179643 times.
✓ Branch 3 taken 196353 times.
✓ Branch 4 taken 169424 times.
706556 switch(side)
5599 {
5600 case up:
5601 322272 overcombo2(dest,x,y,
5602 161136 DoorComboSets[d].bombdoorcombo_u[0],
5603 161136 DoorComboSets[d].bombdoorcset_u[0]);
5604 322272 overcombo2(dest,x+16,y,
5605 161136 DoorComboSets[d].bombdoorcombo_u[1],
5606 161136 DoorComboSets[d].bombdoorcset_u[1]);
5607 161136 break;
5608
5609 case down:
5610 359286 overcombo2(dest,x,y,
5611 179643 DoorComboSets[d].bombdoorcombo_d[0],
5612 179643 DoorComboSets[d].bombdoorcset_d[0]);
5613 359286 overcombo2(dest,x+16,y,
5614 179643 DoorComboSets[d].bombdoorcombo_d[1],
5615 179643 DoorComboSets[d].bombdoorcset_d[1]);
5616 179643 break;
5617
5618 case left:
5619 392706 overcombo2(dest,x,y,
5620 196353 DoorComboSets[d].bombdoorcombo_l[0],
5621 196353 DoorComboSets[d].bombdoorcset_l[0]);
5622 392706 overcombo2(dest,x,y+16,
5623 196353 DoorComboSets[d].bombdoorcombo_l[1],
5624 196353 DoorComboSets[d].bombdoorcset_l[1]);
5625 392706 overcombo2(dest,x,y+16,
5626 196353 DoorComboSets[d].bombdoorcombo_l[2],
5627 196353 DoorComboSets[d].bombdoorcset_l[2]);
5628 196353 break;
5629
5630 case right:
5631 338848 overcombo2(dest,x,y,
5632 169424 DoorComboSets[d].bombdoorcombo_r[0],
5633 169424 DoorComboSets[d].bombdoorcset_r[0]);
5634 338848 overcombo2(dest,x,y+16,
5635 169424 DoorComboSets[d].bombdoorcombo_r[1],
5636 169424 DoorComboSets[d].bombdoorcset_r[1]);
5637 338848 overcombo2(dest,x,y+16,
5638 169424 DoorComboSets[d].bombdoorcombo_r[2],
5639 169424 DoorComboSets[d].bombdoorcset_r[2]);
5640 169424 break;
5641 }
5642 706556 }
5643
5644 47568 void update_door(mapscr* scr, int32_t side, int32_t door, bool even_walls)
5645 {
5646
7/8
✓ Branch 0 taken 47460 times.
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 47460 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22925 times.
✓ Branch 5 taken 24535 times.
✓ Branch 6 taken 530 times.
✓ Branch 7 taken 22395 times.
47568 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5647 25173 return;
5648
5649 int32_t doortype;
5650
5651
10/12
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 655 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12492 times.
✓ Branch 5 taken 910 times.
✓ Branch 6 taken 1553 times.
✓ Branch 7 taken 3192 times.
✓ Branch 8 taken 1694 times.
✓ Branch 9 taken 172 times.
✓ Branch 10 taken 67 times.
✓ Branch 11 taken 1138 times.
22395 switch(door)
5652 {
5653 case dWALL:
5654 doortype=dt_wall;
5655 break;
5656
5657 case dWALK:
5658 doortype=dt_walk;
5659 break;
5660
5661 case dOPEN:
5662 12492 doortype=dt_pass;
5663 12492 break;
5664
5665 case dLOCKED:
5666 910 doortype=dt_lock;
5667 910 break;
5668
5669 case dUNLOCKED:
5670 1553 doortype=dt_olck;
5671 1553 break;
5672
5673 case dSHUTTER:
5674
3/4
✓ Branch 0 taken 2783 times.
✓ Branch 1 taken 409 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2783 times.
3192 if(screenscrolling && ((HeroDir()^1)==side))
5675 {
5676 doortype=dt_osht;
5677 get_screen_state(scr->screen).open_doors = -4;
5678 break;
5679 }
5680
5681 [[fallthrough]];
5682 case d1WAYSHUTTER:
5683 3714 doortype=dt_shut;
5684 3714 break;
5685
5686 case dOPENSHUTTER:
5687 1694 doortype=dt_osht;
5688 1694 break;
5689
5690 case dBOSS:
5691 172 doortype=dt_boss;
5692 172 break;
5693
5694 case dOPENBOSS:
5695 67 doortype=dt_obos;
5696 67 break;
5697
5698 case dBOMBED:
5699 1138 doortype=dt_bomb;
5700 1138 break;
5701
5702 default:
5703 655 return;
5704 }
5705
5706
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 5629 times.
✓ Branch 2 taken 5770 times.
✓ Branch 3 taken 5111 times.
✓ Branch 4 taken 5230 times.
21740 switch(side)
5707 {
5708 case up:
5709 5629 put_door(scr,nullptr,7,side,doortype,false,even_walls);
5710 5629 break;
5711
5712 case down:
5713 5770 put_door(scr,nullptr,151,side,doortype,false,even_walls);
5714 5770 break;
5715
5716 case left:
5717 5111 put_door(scr,nullptr,64,side,doortype,false,even_walls);
5718 5111 break;
5719
5720 case right:
5721 5230 put_door(scr,nullptr,78,side,doortype,false,even_walls);
5722 5230 break;
5723 }
5724 47568 }
5725
5726 6504 void putdoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t door, bool redraw, bool even_walls)
5727 {
5728 /*
5729 #define dWALL 0 // 000 0
5730 #define dBOMB 6 // 011 0
5731 #define 8 // 100 0
5732 enum {dt_pass=0, dt_lock, dt_shut, dt_boss, dt_olck, dt_osht, dt_obos, dt_wall, dt_bomb, dt_walk, dt_max};
5733 */
5734
5735
7/8
✓ Branch 0 taken 6504 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6500 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 6417 times.
✓ Branch 5 taken 83 times.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 6409 times.
6504 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5736 91 return;
5737
5738 int32_t doortype;
5739
5740
8/12
✓ Branch 0 taken 227 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 362 times.
✓ Branch 7 taken 1530 times.
✓ Branch 8 taken 3958 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 51 times.
✓ Branch 11 taken 231 times.
6413 switch(door)
5741 {
5742 case dWALL:
5743 doortype=dt_wall;
5744 break;
5745
5746 case dWALK:
5747 doortype=dt_walk;
5748 break;
5749
5750 case dOPEN:
5751 50 doortype=dt_pass;
5752 50 break;
5753
5754 case dLOCKED:
5755 doortype=dt_lock;
5756 break;
5757
5758 case dUNLOCKED:
5759 362 doortype=dt_olck;
5760 362 break;
5761
5762 case dSHUTTER:
5763
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1530 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1530 if(screenscrolling && ((HeroDir()^1)==side))
5764 {
5765 doortype=dt_osht;
5766 get_screen_state(cur_screen).open_doors = -4;
5767 break;
5768 }
5769
5770 [[fallthrough]];
5771 case d1WAYSHUTTER:
5772 1757 doortype=dt_shut;
5773 1757 break;
5774
5775 case dOPENSHUTTER:
5776 3958 doortype=dt_osht;
5777 3958 break;
5778
5779 case dBOSS:
5780 4 doortype=dt_boss;
5781 4 break;
5782
5783 case dOPENBOSS:
5784 51 doortype=dt_obos;
5785 51 break;
5786
5787 case dBOMBED:
5788 231 doortype=dt_bomb;
5789 231 break;
5790
5791 default:
5792 return;
5793 }
5794
5795
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 1860 times.
✓ Branch 2 taken 1357 times.
✓ Branch 3 taken 1514 times.
✓ Branch 4 taken 1682 times.
6413 switch(side)
5796 {
5797 case up:
5798
2/2
✓ Branch 0 taken 1791 times.
✓ Branch 1 taken 69 times.
1860 switch(door)
5799 {
5800 case dBOMBED:
5801
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
138 if(redraw)
5802 {
5803 69 over_door(scr,dest,39,side,0,0);
5804 69 }
5805 [[fallthrough]];
5806 default:
5807 1860 put_door(scr,dest,7,side,doortype,redraw, even_walls);
5808 1860 break;
5809 }
5810
5811 1860 break;
5812
5813 case down:
5814
2/2
✓ Branch 0 taken 1318 times.
✓ Branch 1 taken 39 times.
1357 switch(door)
5815 {
5816 case dBOMBED:
5817
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
78 if(redraw)
5818 {
5819 39 over_door(scr,dest,135,side,0,0);
5820 39 }
5821 [[fallthrough]];
5822 default:
5823 1357 put_door(scr,dest,151,side,doortype,redraw, even_walls);
5824 1357 break;
5825 }
5826
5827 1357 break;
5828
5829 case left:
5830
2/2
✓ Branch 0 taken 1463 times.
✓ Branch 1 taken 51 times.
1514 switch(door)
5831 {
5832 case dBOMBED:
5833
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
102 if(redraw)
5834 {
5835 51 over_door(scr,dest,66,side,0,0);
5836 51 }
5837 [[fallthrough]];
5838 default:
5839 1514 put_door(scr,dest,64,side,doortype,redraw, even_walls);
5840 1514 break;
5841 }
5842
5843 1514 break;
5844
5845 case right:
5846
2/2
✓ Branch 0 taken 1610 times.
✓ Branch 1 taken 72 times.
1682 switch(door)
5847 {
5848 case dBOMBED:
5849
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
144 if(redraw)
5850 {
5851 72 over_door(scr,dest,77,side,0,0);
5852 72 }
5853 [[fallthrough]];
5854 default:
5855 1682 put_door(scr,dest,78,side,doortype,redraw, even_walls);
5856 1682 break;
5857 }
5858
5859 1682 break;
5860 }
5861 6504 }
5862
5863 586 void putcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5864 {
5865
1/2
✓ Branch 0 taken 586 times.
✗ Branch 1 not taken.
586 if(combo!=0)
5866 {
5867 586 putcombo(dest,x, y, combo, cset);
5868 586 }
5869 586 }
5870
5871 293 void overcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5872 {
5873
2/2
✓ Branch 0 taken 219 times.
✓ Branch 1 taken 74 times.
293 if(combo!=0)
5874 {
5875 219 overcombo(dest,x, y, combo, cset);
5876 219 }
5877 293 }
5878
5879 125 void showbombeddoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t offx, int32_t offy)
5880 {
5881 125 int32_t d = scr->door_combo_set;
5882
5883
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 37 times.
125 switch(side)
5884 {
5885 case up:
5886 86 putcombo_not_zero(dest,((7&15)<<4) + offx,(7&0xF0) + offy,
5887 43 DoorComboSets[d].doorcombo_u[dt_bomb][0],
5888 43 DoorComboSets[d].doorcset_u[dt_bomb][0]);
5889 86 putcombo_not_zero(dest,((8&15)<<4) + offx,(8&0xF0) + offy,
5890 43 DoorComboSets[d].doorcombo_u[dt_bomb][1],
5891 43 DoorComboSets[d].doorcset_u[dt_bomb][1]);
5892 86 putcombo_not_zero(dest,((23&15)<<4) + offx,(23&0xF0) + offy,
5893 43 DoorComboSets[d].doorcombo_u[dt_bomb][2],
5894 43 DoorComboSets[d].doorcset_u[dt_bomb][2]);
5895 86 putcombo_not_zero(dest,((24&15)<<4) + offx,(24&0xF0) + offy,
5896 43 DoorComboSets[d].doorcombo_u[dt_bomb][3],
5897 43 DoorComboSets[d].doorcset_u[dt_bomb][3]);
5898 86 overcombo_not_zero(dest,((39&15)<<4) + offx,(39&0xF0) + offy,
5899 43 DoorComboSets[d].bombdoorcombo_u[0],
5900 43 DoorComboSets[d].bombdoorcset_u[0]);
5901 86 overcombo_not_zero(dest,((40&15)<<4) + offx,(40&0xF0) + offy,
5902 43 DoorComboSets[d].bombdoorcombo_u[1],
5903 43 DoorComboSets[d].bombdoorcset_u[1]);
5904 43 break;
5905
5906 case down:
5907 78 putcombo_not_zero(dest,((151&15)<<4) + offx,(151&0xF0) + offy,
5908 39 DoorComboSets[d].doorcombo_d[dt_bomb][0],
5909 39 DoorComboSets[d].doorcset_d[dt_bomb][0]);
5910 78 putcombo_not_zero(dest,((152&15)<<4) + offx,(152&0xF0) + offy,
5911 39 DoorComboSets[d].doorcombo_d[dt_bomb][1],
5912 39 DoorComboSets[d].doorcset_d[dt_bomb][1]);
5913 78 putcombo_not_zero(dest,((167&15)<<4) + offx,(167&0xF0) + offy,
5914 39 DoorComboSets[d].doorcombo_d[dt_bomb][2],
5915 39 DoorComboSets[d].doorcset_d[dt_bomb][2]);
5916 78 putcombo_not_zero(dest,((168&15)<<4) + offx,(168&0xF0) + offy,
5917 39 DoorComboSets[d].doorcombo_d[dt_bomb][3],
5918 39 DoorComboSets[d].doorcset_d[dt_bomb][3]);
5919 78 overcombo_not_zero(dest,((135&15)<<4) + offx,(135&0xF0) + offy,
5920 39 DoorComboSets[d].bombdoorcombo_d[0],
5921 39 DoorComboSets[d].bombdoorcset_d[0]);
5922 78 overcombo_not_zero(dest,((136&15)<<4) + offx,(136&0xF0) + offy,
5923 39 DoorComboSets[d].bombdoorcombo_d[1],
5924 39 DoorComboSets[d].bombdoorcset_d[1]);
5925 39 break;
5926
5927 case left:
5928 12 putcombo_not_zero(dest,((64&15)<<4) + offx,(64&0xF0) + offy,
5929 6 DoorComboSets[d].doorcombo_l[dt_bomb][0],
5930 6 DoorComboSets[d].doorcset_l[dt_bomb][0]);
5931 12 putcombo_not_zero(dest,((65&15)<<4) + offx,(65&0xF0) + offy,
5932 6 DoorComboSets[d].doorcombo_l[dt_bomb][1],
5933 6 DoorComboSets[d].doorcset_l[dt_bomb][1]);
5934 12 putcombo_not_zero(dest,((80&15)<<4) + offx,(80&0xF0) + offy,
5935 6 DoorComboSets[d].doorcombo_l[dt_bomb][2],
5936 6 DoorComboSets[d].doorcset_l[dt_bomb][2]);
5937 12 putcombo_not_zero(dest,((81&15)<<4) + offx,(81&0xF0) + offy,
5938 6 DoorComboSets[d].doorcombo_l[dt_bomb][3],
5939 6 DoorComboSets[d].doorcset_l[dt_bomb][3]);
5940 12 putcombo_not_zero(dest,((96&15)<<4) + offx,(96&0xF0) + offy,
5941 6 DoorComboSets[d].doorcombo_l[dt_bomb][4],
5942 6 DoorComboSets[d].doorcset_l[dt_bomb][4]);
5943 12 putcombo_not_zero(dest,((97&15)<<4) + offx,(97&0xF0) + offy,
5944 6 DoorComboSets[d].doorcombo_l[dt_bomb][5],
5945 6 DoorComboSets[d].doorcset_l[dt_bomb][5]);
5946 12 overcombo_not_zero(dest,((66&15)<<4) + offx,(66&0xF0) + offy,
5947 6 DoorComboSets[d].bombdoorcombo_l[0],
5948 6 DoorComboSets[d].bombdoorcset_l[0]);
5949 12 overcombo_not_zero(dest,((82&15)<<4) + offx,(82&0xF0) + offy,
5950 6 DoorComboSets[d].bombdoorcombo_l[1],
5951 6 DoorComboSets[d].bombdoorcset_l[1]);
5952 12 overcombo_not_zero(dest,((98&15)<<4) + offx,(98&0xF0) + offy,
5953 6 DoorComboSets[d].bombdoorcombo_l[2],
5954 6 DoorComboSets[d].bombdoorcset_l[2]);
5955 6 break;
5956
5957 case right:
5958 74 putcombo_not_zero(dest,((78&15)<<4) + offx,(78&0xF0) + offy,
5959 37 DoorComboSets[d].doorcombo_r[dt_bomb][0],
5960 37 DoorComboSets[d].doorcset_r[dt_bomb][0]);
5961 74 putcombo_not_zero(dest,((79&15)<<4) + offx,(79&0xF0) + offy,
5962 37 DoorComboSets[d].doorcombo_r[dt_bomb][1],
5963 37 DoorComboSets[d].doorcset_r[dt_bomb][1]);
5964 74 putcombo_not_zero(dest,((94&15)<<4) + offx,(94&0xF0) + offy,
5965 37 DoorComboSets[d].doorcombo_r[dt_bomb][2],
5966 37 DoorComboSets[d].doorcset_r[dt_bomb][2]);
5967 74 putcombo_not_zero(dest,((95&15)<<4) + offx,(95&0xF0) + offy,
5968 37 DoorComboSets[d].doorcombo_r[dt_bomb][3],
5969 37 DoorComboSets[d].doorcset_r[dt_bomb][3]);
5970 74 putcombo_not_zero(dest,((110&15)<<4) + offx,(110&0xF0) + offy,
5971 37 DoorComboSets[d].doorcombo_r[dt_bomb][4],
5972 37 DoorComboSets[d].doorcset_r[dt_bomb][4]);
5973 74 putcombo_not_zero(dest,((111&15)<<4) + offx,(111&0xF0) + offy,
5974 37 DoorComboSets[d].doorcombo_r[dt_bomb][5],
5975 37 DoorComboSets[d].doorcset_r[dt_bomb][5]);
5976 74 overcombo_not_zero(dest,((77&15)<<4) + offx,(77&0xF0) + offy,
5977 37 DoorComboSets[d].bombdoorcombo_r[0],
5978 37 DoorComboSets[d].bombdoorcset_r[0]);
5979 74 overcombo_not_zero(dest,((93&15)<<4) + offx,(93&0xF0) + offy,
5980 37 DoorComboSets[d].bombdoorcombo_r[1],
5981 37 DoorComboSets[d].bombdoorcset_r[1]);
5982 74 overcombo_not_zero(dest,((109&15)<<4) + offx,(109&0xF0) + offy,
5983 37 DoorComboSets[d].bombdoorcombo_r[2],
5984 37 DoorComboSets[d].bombdoorcset_r[2]);
5985 37 break;
5986 }
5987 125 }
5988
5989 5530089 void openshutters(mapscr* scr)
5990 {
5991 5530089 bool opened_door = false;
5992
2/2
✓ Branch 0 taken 5530089 times.
✓ Branch 1 taken 22120356 times.
27650445 for(int32_t i=0; i<4; i++)
5993
2/2
✓ Branch 0 taken 22116398 times.
✓ Branch 1 taken 3958 times.
22124314 if(scr->door[i]==dSHUTTER)
5994 {
5995 3958 putdoor(scr, scrollbuf, i, dOPENSHUTTER);
5996 3958 scr->door[i]=dOPENSHUTTER;
5997 3958 opened_door = true;
5998 3958 }
5999
6000 5530089 auto& combo_cache = combo_caches::shutter;
6001 2231904891 for_every_combo_in_screen(create_screen_handles(scr), [&](const auto& handle) {
6002
3/4
✓ Branch 0 taken 2224452201 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 1922594 times.
✗ Branch 3 not taken.
2226374802 if (!combo_cache.minis[handle.data()].shutter)
6003 2226374795 return;
6004
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
14 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
6005 7 return trig.trigger_flags.get(TRIGFLAG_SHUTTER);
6006 });
6007 2226374802 });
6008
6009
2/2
✓ Branch 0 taken 5527358 times.
✓ Branch 1 taken 2731 times.
5530089 if(opened_door)
6010 2731 sfx(WAV_DOOR);
6011 5530089 }
6012
6013 15715672 void clear_darkroom_bitmaps()
6014 {
6015 15715672 clear_to_color(darkscr_bmp, game->get_darkscr_color());
6016 15715672 clear_to_color(darkscr_bmp_trans, game->get_darkscr_color());
6017 15715672 }
6018
6019 16743908 bool is_dark(const mapscr* scr)
6020 {
6021 16743908 bool dark = scr->flags&fDARK;
6022
2/2
✓ Branch 0 taken 3722 times.
✓ Branch 1 taken 16740186 times.
16743908 if (region_is_lit) return !dark;
6023 16740186 return dark;
6024 16743908 }
6025
6026 53189 bool scrolling_is_dark(const mapscr* scr)
6027 {
6028 53189 bool dark = scr->flags&fDARK;
6029
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 53187 times.
53189 if (scrolling_region_is_lit) return !dark;
6030 53187 return dark;
6031 53189 }
6032
6033 38440 bool is_any_dark()
6034 {
6035 38440 bool dark = false;
6036 78136 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
6037 39696 dark |= (bool)(is_dark(scr));
6038 39696 });
6039 38440 return dark;
6040 }
6041
6042
3/4
✓ Branch 0 taken 3010 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2580 times.
✓ Branch 3 taken 430 times.
3010 static mapscr prev_origin_scrs[7];
6043 430 static std::set<int> loadscr_ffc_script_ids_to_remove;
6044
6045 static void handle_screen_overlay(const std::vector<mapscr*>& screens)
6046 {
6047 mapscr* base_scr = screens[0];
6048 mapscr* previous_scr = &prev_origin_scrs[0];
6049
6050 for (int i = 0; i < 176; i++)
6051 {
6052 if (base_scr->data[i] == 0)
6053 {
6054 base_scr->data[i] = previous_scr->data[i];
6055 base_scr->sflag[i] = previous_scr->sflag[i];
6056 base_scr->cset[i] = previous_scr->cset[i];
6057 }
6058 }
6059
6060 for (int i = 0; i < 6; i++)
6061 {
6062 if (previous_scr->layermap[i] > 0 && base_scr->layermap[i] > 0)
6063 {
6064 int lm = (base_scr->layermap[i]-1)*MAPSCRS+base_scr->layerscreen[i];
6065 int fm = (previous_scr->layermap[i]-1)*MAPSCRS+previous_scr->layerscreen[i];
6066
6067 for (int j = 0; j < 176; j++)
6068 {
6069 if (TheMaps[lm].data[j] == 0)
6070 {
6071 TheMaps[lm].data[j] = TheMaps[fm].data[j];
6072 TheMaps[lm].sflag[j] = TheMaps[fm].sflag[j];
6073 TheMaps[lm].cset[j] = TheMaps[fm].cset[j];
6074 }
6075 }
6076 }
6077 }
6078
6079 for (int i = 1; i <= 6; i++)
6080 {
6081 mapscr* scr = screens[i];
6082 previous_scr = &prev_origin_scrs[i];
6083
6084 if (scr->layermap[i] > 0)
6085 {
6086 for (int y = 0; y < 11; y++)
6087 {
6088 for (int x = 0; x < 16; x++)
6089 {
6090 int c = y*16+x;
6091
6092 if (scr->data[c]==0)
6093 {
6094 scr->data[c] = previous_scr->data[c];
6095 scr->sflag[c] = previous_scr->sflag[c];
6096 scr->cset[c] = previous_scr->cset[c];
6097 }
6098 }
6099 }
6100 }
6101 }
6102 }
6103
6104 38780 static void load_a_screen_and_layers_init(int dmap, int screen, int ldir, bool screen_overlay, bool ffc_overlay)
6105 {
6106 38780 std::vector<mapscr*> screens;
6107
6108
1/2
✓ Branch 0 taken 38780 times.
✗ Branch 1 not taken.
38780 const mapscr* source = get_canonical_scr(cur_map, screen);
6109
2/4
✓ Branch 0 taken 38780 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38780 times.
✗ Branch 3 not taken.
38780 mapscr* base_scr = new mapscr(*source);
6110 38780 temporary_screens[screen*7] = base_scr;
6111
1/2
✓ Branch 0 taken 38780 times.
✗ Branch 1 not taken.
38780 screens.push_back(base_scr);
6112
6113 38780 base_scr->valid |= mVALID; // layer 0 is always valid
6114
6115
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 37536 times.
38780 if (screen == cur_screen)
6116 37536 origin_scr = base_scr;
6117
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 37536 times.
38780 if (screen == Hero.current_screen)
6118 37536 hero_scr = prev_hero_scr = base_scr;
6119
6120
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 38636 times.
38780 if (source->script > 0)
6121
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
6122
6123
2/2
✓ Branch 0 taken 38780 times.
✓ Branch 1 taken 232680 times.
271460 for (int i = 0; i < 6; i++)
6124 {
6125
2/2
✓ Branch 0 taken 176203 times.
✓ Branch 1 taken 56477 times.
232680 if(source->layermap[i]>0)
6126 {
6127
3/6
✓ Branch 0 taken 56477 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 56477 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 56477 times.
✗ Branch 5 not taken.
56477 mapscr* layer_scr = new mapscr(*get_canonical_scr(source->layermap[i]-1, source->layerscreen[i]));
6128 56477 layer_scr->map = cur_map;
6129 56477 layer_scr->screen = screen;
6130 56477 layer_scr->valid |= mVALID;
6131
1/2
✓ Branch 0 taken 56477 times.
✗ Branch 1 not taken.
56477 screens.push_back(layer_scr);
6132 56477 }
6133 else
6134 {
6135
2/4
✓ Branch 0 taken 176203 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 176203 times.
✗ Branch 3 not taken.
176203 mapscr* layer_scr = new mapscr();
6136 176203 layer_scr->map = cur_map;
6137 176203 layer_scr->screen = screen;
6138
1/2
✓ Branch 0 taken 176203 times.
✗ Branch 1 not taken.
176203 screens.push_back(layer_scr);
6139 }
6140 232680 temporary_screens[screen*7+i+1] = screens[i+1];
6141 232680 }
6142
6143
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38780 times.
38780 if (screen_overlay)
6144 handle_screen_overlay(screens);
6145
6146
2/2
✓ Branch 0 taken 145 times.
✓ Branch 1 taken 38635 times.
38780 if (ffc_overlay)
6147 {
6148 145 mapscr* previous_scr = &prev_origin_scrs[0];
6149
1/2
✓ Branch 0 taken 145 times.
✗ Branch 1 not taken.
145 int num_ffcs = previous_scr->numFFC();
6150
2/2
✓ Branch 0 taken 4640 times.
✓ Branch 1 taken 145 times.
4785 for (int i = 0; i < num_ffcs; i++)
6151 {
6152
2/2
✓ Branch 0 taken 4365 times.
✓ Branch 1 taken 275 times.
4640 if ((previous_scr->ffcs[i].flags&ffc_carryover))
6153 {
6154
2/4
✓ Branch 0 taken 275 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 275 times.
✗ Branch 3 not taken.
275 auto& ffc = base_scr->getFFC(i) = previous_scr->ffcs[i];
6155 275 ffc.screen_spawned = screen;
6156
6157
1/2
✓ Branch 0 taken 275 times.
✗ Branch 1 not taken.
275 ffc_id_t ffc_id = get_region_screen_offset(screen)*MAXFFCS + i;
6158
1/2
✓ Branch 0 taken 275 times.
✗ Branch 1 not taken.
275 loadscr_ffc_script_ids_to_remove.erase(ffc_id);
6159
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 275 times.
275 if (previous_scr->ffcs[i].flags&ffc_scriptreset)
6160 {
6161 FFCore.reset_script_engine_data(ScriptType::FFC, ffc_id);
6162 }
6163 275 }
6164 4640 }
6165 145 }
6166
6167
1/2
✓ Branch 0 taken 38780 times.
✗ Branch 1 not taken.
2252362 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
6168
1/2
✓ Branch 0 taken 38780 times.
✗ Branch 1 not taken.
38780 int num_ffcs = base_scr->numFFC();
6169
2/2
✓ Branch 0 taken 1106791 times.
✓ Branch 1 taken 38780 times.
1145571 for (word i = 0; i < num_ffcs; i++)
6170 {
6171 1106791 base_scr->ffcs[i].screen_spawned = screen;
6172 1106791 base_scr->ffcs[i].x += offx;
6173 1106791 base_scr->ffcs[i].y += offy;
6174 1106791 }
6175 38780 }
6176
6177 38780 static void load_a_screen_and_layers_post(int dmap, int screen, int ldir)
6178 {
6179 38780 mapscr* base_scr = get_scr(screen);
6180 38780 int mi = mapind(cur_map, screen);
6181
6182 // Apply perm secrets, if applicable.
6183
2/2
✓ Branch 0 taken 11520 times.
✓ Branch 1 taken 27260 times.
38780 if (canPermSecret(dmap, screen))
6184 {
6185
2/2
✓ Branch 0 taken 24354 times.
✓ Branch 1 taken 2906 times.
27260 if(game->maps[mi] & mSECRET) // if special stuff done before
6186 {
6187 2906 reveal_hidden_stairs(base_scr, screen, false);
6188 2906 trigger_secrets_for_screen(TriggerSource::SecretsScreenState, base_scr, false);
6189 2906 }
6190
2/2
✓ Branch 0 taken 27257 times.
✓ Branch 1 taken 3 times.
27260 if(game->maps[mi] & mLIGHTBEAM) // if special stuff done before
6191 {
6192
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 3 times.
24 for (int layer = 0; layer <= 6; layer++)
6193 {
6194 21 mapscr* layer_scr = get_scr_layer(screen, layer);
6195
2/2
✓ Branch 0 taken 3696 times.
✓ Branch 1 taken 21 times.
3717 for (int pos = 0; pos < 176; pos++)
6196 {
6197 3696 newcombo const* cmb = &combobuf[layer_scr->data[pos]];
6198
2/2
✓ Branch 0 taken 3693 times.
✓ Branch 1 taken 3 times.
3696 if(cmb->type == cLIGHTTARGET)
6199 {
6200
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!(cmb->usrflags&cflag1)) //Unlit version
6201 {
6202 3 layer_scr->data[pos] += 1;
6203 3 }
6204 3 }
6205 3696 }
6206 21 }
6207 3 }
6208 27260 }
6209
6210 38780 auto screen_handles = create_screen_handles(base_scr);
6211
6212 38780 int destlvl = DMaps[dmap].level;
6213 38780 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
6214 38780 toggle_gswitches_load(screen_handles);
6215
6216 38780 bool should_check_for_state_things = (screen < 0x80);
6217
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 37873 times.
38780 if (should_check_for_state_things)
6218 {
6219
2/2
✓ Branch 0 taken 37439 times.
✓ Branch 1 taken 434 times.
37873 if (game->maps[mi]&mLOCKBLOCK)
6220 434 remove_lockblocks(screen_handles);
6221
2/2
✓ Branch 0 taken 37784 times.
✓ Branch 1 taken 89 times.
37873 if (game->maps[mi]&mBOSSLOCKBLOCK)
6222 89 remove_bosslockblocks(screen_handles);
6223
2/2
✓ Branch 0 taken 37705 times.
✓ Branch 1 taken 168 times.
37873 if (game->maps[mi]&mCHEST)
6224 168 remove_chests(screen_handles);
6225
1/2
✓ Branch 0 taken 37873 times.
✗ Branch 1 not taken.
37873 if (game->maps[mi]&mLOCKEDCHEST)
6226 remove_lockedchests(screen_handles);
6227
2/2
✓ Branch 0 taken 37862 times.
✓ Branch 1 taken 11 times.
37873 if (game->maps[mi]&mBOSSCHEST)
6228 11 remove_bosschests(screen_handles);
6229
6230 37873 clear_xdoors_mi(screen_handles, mi, true);
6231 37873 clear_xstatecombos_mi(screen_handles, mi, true);
6232 37873 }
6233
6234 // check doors
6235
2/2
✓ Branch 0 taken 27259 times.
✓ Branch 1 taken 11521 times.
38780 if (isdungeon(dmap, screen))
6236 {
6237
2/2
✓ Branch 0 taken 46084 times.
✓ Branch 1 taken 11521 times.
57605 for(int32_t i=0; i<4; i++)
6238 {
6239 46084 int32_t door=base_scr->door[i];
6240
6241
5/5
✓ Branch 0 taken 5303 times.
✓ Branch 1 taken 36475 times.
✓ Branch 2 taken 2372 times.
✓ Branch 3 taken 230 times.
✓ Branch 4 taken 1704 times.
46084 switch(door)
6242 {
6243 case d1WAYSHUTTER:
6244 case dSHUTTER:
6245
3/4
✓ Branch 0 taken 1694 times.
✓ Branch 1 taken 3609 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1694 times.
5303 if ((ldir^1)==i && screen == Hero.current_screen)
6246 {
6247 1694 base_scr->door[i]=dOPENSHUTTER;
6248 1694 }
6249
6250 5303 get_screen_state(screen).open_doors = -4;
6251 5303 break;
6252
6253 case dLOCKED:
6254
3/4
✓ Branch 0 taken 2372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1473 times.
✓ Branch 3 taken 899 times.
2372 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6255 {
6256 1473 base_scr->door[i]=dUNLOCKED;
6257 1473 }
6258
6259 2372 break;
6260
6261 case dBOSS:
6262
3/4
✓ Branch 0 taken 230 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 168 times.
230 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6263 {
6264 62 base_scr->door[i]=dOPENBOSS;
6265 62 }
6266
6267 230 break;
6268
6269 case dBOMB:
6270
3/4
✓ Branch 0 taken 1704 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1087 times.
✓ Branch 3 taken 617 times.
1704 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6271 {
6272 1087 base_scr->door[i]=dBOMBED;
6273 1087 }
6274
6275 1704 break;
6276 }
6277
6278 46084 update_door(base_scr, i, base_scr->door[i]);
6279
6280
4/4
✓ Branch 0 taken 41517 times.
✓ Branch 1 taken 4567 times.
✓ Branch 2 taken 736 times.
✓ Branch 3 taken 40781 times.
46084 if(door==dSHUTTER||door==d1WAYSHUTTER)
6281 {
6282 5303 base_scr->door[i]=door;
6283 5303 }
6284 46084 }
6285 11521 }
6286
6287
2/2
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 38641 times.
38780 if (!(base_scr->flags3 & fCYCLEONINIT))
6288 38641 return;
6289
6290
2/2
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 973 times.
1112 for (int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6291 {
6292
4/4
✓ Branch 0 taken 834 times.
✓ Branch 1 taken 139 times.
✓ Branch 2 taken 383 times.
✓ Branch 3 taken 451 times.
973 if (j<0 || base_scr->layermap[j] > 0)
6293 {
6294 522 mapscr* layer_scr = get_scr_layer(screen, j + 1);
6295
3/4
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 139 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 383 times.
522 mapscr* layerscreen= (j<0 ? base_scr : layer_scr->valid ? layer_scr :
6296 &TheMaps[(base_scr->layermap[j]-1)*MAPSCRS]+base_scr->layerscreen[j]);
6297
6298
2/2
✓ Branch 0 taken 91872 times.
✓ Branch 1 taken 522 times.
92394 for(int32_t i=0; i<176; ++i)
6299 {
6300 91872 int32_t c=layerscreen->data[i];
6301
6302 // New screen flag: Cycle Combos At Screen Init
6303
5/6
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 91807 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 29 times.
✗ Branch 5 not taken.
91872 if(combobuf[c].nextcombo != 0 && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6304 {
6305 65 int32_t r = 0;
6306
6307
4/4
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 65 times.
149 while(combobuf[c].can_cycle() && r++ < 10)
6308 {
6309 84 newcombo const& cmb = combobuf[c];
6310 84 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6311
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6312 84 layerscreen->data[i] = cid;
6313
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 69 times.
84 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6314
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6315 84 c = layerscreen->data[i];
6316 }
6317 65 }
6318 91872 }
6319 522 }
6320 973 }
6321 38780 }
6322
6323 // Set `cur_screen` to `screen` and load new screens into temporary memory.
6324 //
6325 // Called anytime a player moves to a new screen (either via warping, scrolling, continue, starting
6326 // the game, etc...)
6327 //
6328 // Note: for regions, only the initial screen load calls this function. Simply walking between
6329 // screens in the same region does not use this, because every screen in a region is loaded into
6330 // temporary memory up front.
6331 //
6332 // If scr >= 0x80, `Hero.current_screen` will be saved to `home_screen` and also be loaded into
6333 // `special_warp_return_scr`.
6334 //
6335 // If origin_screen_overlay is true, the old origin_scr combos will be copied to the new origin_scr combos
6336 // on all layers (but only where the new screen has a 0 combo).
6337 //
6338 // TODO: loadscr should set curdmap, but currently callers do that.
6339 37536 void loadscr(int32_t destdmap, int32_t screen, int32_t ldir, bool origin_screen_overlay, bool no_x80_dir)
6340 {
6341 37536 zapp_reporting_set_tag("screen", screen);
6342
2/2
✓ Branch 0 taken 9316 times.
✓ Branch 1 taken 28220 times.
37536 if (destdmap != -1)
6343 9316 zapp_reporting_set_tag("dmap", destdmap);
6344
6345 37536 int32_t orig_destdmap = destdmap;
6346
2/2
✓ Branch 0 taken 9316 times.
✓ Branch 1 taken 28220 times.
37536 if (destdmap < 0) destdmap = cur_dmap;
6347
6348
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37536 times.
37536 if (replay_is_active())
6349 {
6350
2/2
✓ Branch 0 taken 28220 times.
✓ Branch 1 taken 9316 times.
37536 if (orig_destdmap != -1)
6351 {
6352
2/2
✓ Branch 0 taken 8245 times.
✓ Branch 1 taken 1071 times.
9316 if (strlen(DMaps[orig_destdmap].name) > 0)
6353 {
6354
1/2
✓ Branch 0 taken 8245 times.
✗ Branch 1 not taken.
8245 replay_step_comment(fmt::format("dmap={} {}", orig_destdmap, DMaps[orig_destdmap].name));
6355 8245 }
6356 else
6357 {
6358
1/2
✓ Branch 0 taken 1071 times.
✗ Branch 1 not taken.
1071 replay_step_comment(fmt::format("dmap={}", orig_destdmap));
6359 }
6360 9316 }
6361 37536 replay_step_comment_loadscr(screen);
6362
6363 // Reset the rngs and frame count so that recording steps can be modified without impacting
6364 // behavior of later screens.
6365 37536 replay_sync_rng();
6366 37536 }
6367
6368
2/2
✓ Branch 0 taken 1754088 times.
✓ Branch 1 taken 37536 times.
1791624 for (auto& state : get_screen_states())
6369 1754088 state.second.triggered_secrets = false;
6370 37536 slopes.clear();
6371 37536 Hero.clear_platform_ffc();
6372 37536 timeExitAllGenscript(GENSCR_ST_CHANGE_SCREEN);
6373 37536 clear_darkroom_bitmaps();
6374 37536 msgscr = nullptr;
6375
6376
2/2
✓ Branch 0 taken 52509660 times.
✓ Branch 1 taken 37536 times.
52547196 for (word x=0; x<animated_combos; x++)
6377 {
6378
2/2
✓ Branch 0 taken 21102528 times.
✓ Branch 1 taken 31407132 times.
52509660 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6379 {
6380 21102528 combobuf[animated_combo_table4[x][0]].aclk = 0;
6381 21102528 }
6382 52509660 }
6383 37536 reset_combo_animations2();
6384 37536 region_is_lit = false;
6385
6386 // Legacy features (combo and ffc overlays) may need the previous origin screens during loading
6387 // of the new ones.
6388 37536 bool origin_ffc_overlay = false;
6389
2/2
✓ Branch 0 taken 1175 times.
✓ Branch 1 taken 36361 times.
37536 if (origin_scr)
6390 {
6391
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 36359 times.
36361 if (!(origin_scr->flags5&fNOFFCARRYOVER))
6392 {
6393 36359 int c = origin_scr->numFFC();
6394
2/2
✓ Branch 0 taken 36214 times.
✓ Branch 1 taken 1040673 times.
1076887 for (int i = 0; i < c; i++)
6395 {
6396
2/2
✓ Branch 0 taken 1040528 times.
✓ Branch 1 taken 145 times.
1040673 if (origin_scr->ffcs[i].flags&ffc_carryover)
6397 {
6398 145 origin_ffc_overlay = true;
6399 145 break;
6400 }
6401 1040528 }
6402 36359 }
6403
6404
3/4
✓ Branch 0 taken 36361 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 145 times.
✓ Branch 3 taken 36216 times.
36361 if (origin_screen_overlay || origin_ffc_overlay)
6405 {
6406
2/2
✓ Branch 0 taken 1015 times.
✓ Branch 1 taken 145 times.
1160 for (int i = 0; i <= 6; i++)
6407 {
6408 1015 mapscr* prev_scr = get_scr_layer(cur_screen, i);
6409
1/2
✓ Branch 0 taken 1015 times.
✗ Branch 1 not taken.
1015 if (prev_scr)
6410 1015 prev_origin_scrs[i] = *prev_scr;
6411 else
6412 prev_origin_scrs[i] = {};
6413 1015 }
6414 145 }
6415 36361 }
6416
6417 // When loading a new screen, all previous FFC scripts end, with one exception.
6418 // Based on origin_ffc_overlay, some ffc scripts don't get reset. This set starts with all of
6419 // them, but scripts that need their data to persist will be removed.
6420 37536 loadscr_ffc_script_ids_to_remove.clear();
6421
2/2
✓ Branch 0 taken 94816931 times.
✓ Branch 1 taken 37536 times.
94854467 for (auto& key : scriptEngineDatas | std::views::keys)
6422 {
6423
2/2
✓ Branch 0 taken 93685978 times.
✓ Branch 1 taken 1130953 times.
94816931 if (key.first == ScriptType::FFC)
6424 1130953 loadscr_ffc_script_ids_to_remove.insert(key.second);
6425 }
6426
6427 37536 load_region(destdmap, screen);
6428
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 36629 times.
37536 home_screen = screen >= 0x80 ? Hero.current_screen : cur_screen;
6429 37536 Hero.current_screen = screen;
6430
6431 37536 cpos_clear_all();
6432 37536 FFCore.destroyScriptableObjectsOfType(ScriptType::Screen);
6433 37536 FFCore.clear_combo_scripts();
6434
6435
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 37372 times.
37536 if (is_in_scrolling_region())
6436 {
6437
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6438 {
6439
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6440 {
6441
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool screen_overlay = origin_screen_overlay && screen == cur_screen;
6442
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool ffc_overlay = origin_ffc_overlay && screen == cur_screen;
6443 1408 load_a_screen_and_layers_init(destdmap, screen, ldir, screen_overlay, ffc_overlay);
6444 1408 }
6445 20992 }
6446 164 }
6447 else
6448 {
6449 37372 load_a_screen_and_layers_init(destdmap, screen, ldir, origin_screen_overlay, origin_ffc_overlay);
6450 }
6451
6452 37536 prepare_current_region_handles();
6453
6454
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 37372 times.
37536 if (is_in_scrolling_region())
6455 {
6456
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6457 {
6458
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6459 {
6460 1408 load_a_screen_and_layers_post(destdmap, screen, ldir);
6461 1408 }
6462 20992 }
6463 164 }
6464 else
6465 {
6466 37372 load_a_screen_and_layers_post(destdmap, screen, ldir);
6467 }
6468
6469 // If on a special screen, load the screen the player is currently on (home_screen) into special_warp_return_scr.
6470
2/2
✓ Branch 0 taken 36629 times.
✓ Branch 1 taken 907 times.
37536 if (screen >= 0x80)
6471
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 431 times.
907 loadscr_old(orig_destdmap, home_screen, no_x80_dir ? -1 : ldir, origin_screen_overlay);
6472
6473 37536 update_slope_comboposes();
6474 37536 cpos_force_update();
6475 37536 trig_trigger_groups();
6476
6477
2/2
✓ Branch 0 taken 1130678 times.
✓ Branch 1 taken 37536 times.
1168214 for (int index : loadscr_ffc_script_ids_to_remove)
6478 {
6479 // Note: ideally would use "destroySprite", but during scrolling the previous
6480 // screen's FFCs are still accessible (even though only the new screen's FFC scripts run).
6481 // The only difference is a call to "release_sprite_owned_objects". To defer FFC script
6482 // owned objects being released until the end of the scroll, here "destroyScriptableObject"
6483 // is used instead.
6484 //
6485 // So when is "release_sprite_owned_objects" called for FFCs? For scrolling screen
6486 // transitions, it's at the end of "scrollscr" via "delete_temporary_screens". Otherwise,
6487 // it is called above when "load_region" calls "clear_temporary_screens".
6488 1130678 FFCore.destroyScriptableObject(ScriptType::FFC, index);
6489 }
6490
6491 // "extended height mode" includes the top 56 pixels as part of the visible mapscr viewport,
6492 // allowing for regions to display 4 more rows of combos (as many as ALTTP does). This part of
6493 // screen is normally reserved for the passive subscreen, but in this mode mapscr combos are drawn below it.
6494 // It is up to the quest designer to make their subscreen be actually transparent.
6495 //
6496 // When not in "extended height mode" (otherwise 56 is 0):
6497 // - playing_field_offset: 56, but changes during earthquakes
6498 // - original_playing_field_offset: always 56
6499 //
6500 // These values are used to adjust where things are drawn on screen to account for the passive subscreen. Examples:
6501 // - yofs of sprites
6502 // - bitmap y offsets in draw_screen
6503 // - drawing offsets for putscr, do_layer
6504 // - drawing offsets for various calls to overtile16 (see bomb weapon explosion)
6505 // - lots more
6506 //
6507 // TODO: consider refactor of yofs, make yofs start as 0 by default and add playing_field_offset at draw time?
6508
2/2
✓ Branch 0 taken 142 times.
✓ Branch 1 taken 37394 times.
37536 if (is_extended_height_mode())
6509 {
6510 142 playing_field_offset = 0;
6511 142 original_playing_field_offset = 0;
6512 // A few sprites exist as globals, so we must manually reset them.
6513 142 Hero.yofs = 0;
6514 142 mblock2.yofs = 0;
6515 142 }
6516 else
6517 {
6518 37394 mblock2.yofs = Hero.yofs = playing_field_offset = 56;
6519 37394 original_playing_field_offset = 56;
6520 }
6521 37536 is_any_room_dark = is_any_dark();
6522
6523 37536 game->load_portal();
6524 37536 throwGenScriptEvent(GENSCR_EVENT_CHANGE_SCREEN);
6525
3/4
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 37501 times.
✓ Branch 2 taken 35 times.
✗ Branch 3 not taken.
37536 if (Hero.lift_wpn && get_qr(qr_CARRYABLE_NO_ACROSS_SCREEN))
6526 {
6527 delete Hero.lift_wpn;
6528 Hero.lift_wpn = nullptr;
6529 }
6530
6531 37536 enemy_spawning_has_checked_been_here = false;
6532 37536 markBmap(-1, Hero.current_screen);
6533 37536 Hero.maybe_begin_advanced_maze();
6534 37536 }
6535
6536 // Don't use this directly! Use `loadscr` instead.
6537 907 void loadscr_old(int32_t destdmap, int32_t screen,int32_t ldir,bool overlay)
6538 {
6539
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int32_t destlvl = DMaps[destdmap < 0 ? cur_dmap : destdmap].level;
6540
6541 907 mapscr previous_scr = *special_warp_return_scr;
6542 907 mapscr* scr = special_warp_return_scr;
6543
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 const mapscr* source = get_canonical_scr(cur_map, screen);
6544
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 *scr = *source;
6545
6546
2/2
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 907 times.
6349 for (int i = 1; i <= 6; i++)
6547 {
6548
2/2
✓ Branch 0 taken 5059 times.
✓ Branch 1 taken 383 times.
5442 if (scr->layermap[i-1] > 0)
6549
2/4
✓ Branch 0 taken 383 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 383 times.
✗ Branch 3 not taken.
383 special_warp_return_scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6550 else
6551
2/4
✓ Branch 0 taken 5059 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5059 times.
✗ Branch 3 not taken.
5059 special_warp_return_scrs[i] = {};
6552 5442 }
6553
6554 907 scr->valid |= mVALID; //layer 0 is always valid
6555
6556
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 907 times.
907 if ( source->script > 0 )
6557 {
6558 scr->script = source->script;
6559 for ( int32_t q = 0; q < 8; q++ )
6560 {
6561 scr->screeninitd[q] = source->screeninitd[q];
6562 }
6563 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
6564 }
6565 else
6566 {
6567 907 scr->script = 0;
6568 }
6569
6570
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 if(overlay)
6571 {
6572 for(int32_t c=0; c< 176; ++c)
6573 {
6574 if(scr->data[c]==0)
6575 {
6576 scr->data[c]=previous_scr.data[c];
6577 scr->sflag[c]=previous_scr.sflag[c];
6578 scr->cset[c]=previous_scr.cset[c];
6579 }
6580 }
6581
6582 for(int32_t i=0; i<6; i++)
6583 {
6584 if(previous_scr.layermap[i]>0 && scr->layermap[i]>0)
6585 {
6586 int32_t lm = (scr->layermap[i]-1)*MAPSCRS+scr->layerscreen[i];
6587 int32_t fm = (previous_scr.layermap[i]-1)*MAPSCRS+previous_scr.layerscreen[i];
6588
6589 for(int32_t c=0; c< 176; ++c)
6590 {
6591 if(TheMaps[lm].data[c]==0)
6592 {
6593 TheMaps[lm].data[c] = TheMaps[fm].data[c];
6594 TheMaps[lm].sflag[c] = TheMaps[fm].sflag[c];
6595 TheMaps[lm].cset[c] = TheMaps[fm].cset[c];
6596 }
6597 }
6598 }
6599 }
6600 }
6601
6602
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
29900 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
6603
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int c = scr->numFFC();
6604
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 28993 times.
29900 for (word i = 0; i < c; i++)
6605 {
6606 28993 scr->ffcs[i].screen_spawned = screen;
6607
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].x += offx;
6608
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].y += offy;
6609 28993 }
6610
6611 907 int mi = mapind(cur_map, screen);
6612
6613 // Apply perm secrets, if applicable.
6614
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✓ Branch 3 taken 371 times.
907 if(canPermSecret(destdmap,screen))
6615 {
6616
3/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 332 times.
536 if(game->maps[mi]&mSECRET) // if special stuff done before
6617 {
6618
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 reveal_hidden_stairs(scr, screen, false);
6619
6620
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
6621
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 get_screen_state(special_warp_return_scr->screen).triggered_secrets = true;
6622 204 bool do_replay_comment = true;
6623 204 bool from_active_screen = false;
6624
2/4
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✗ Branch 3 not taken.
204 trigger_secrets_for_screen_internal(create_screen_handles(special_warp_return_scr), from_active_screen, false, -1, do_replay_comment);
6625 204 }
6626
2/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✗ Branch 3 not taken.
536 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6627 {
6628 for (int layer = 0; layer <= 6; layer++)
6629 {
6630 mapscr* tscr = &special_warp_return_scrs[layer];
6631 for (int pos = 0; pos < 176; pos++)
6632 {
6633 newcombo const* cmb = &combobuf[tscr->data[pos]];
6634 if(cmb->type == cLIGHTTARGET)
6635 {
6636 if(!(cmb->usrflags&cflag1)) //Unlit version
6637 {
6638 tscr->data[pos] += 1;
6639 }
6640 }
6641 }
6642 }
6643 }
6644 536 }
6645
6646 screen_handles_t screen_handles;
6647
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 6349 times.
7256 for (int i = 0; i <= 6; i++)
6648
3/4
✓ Branch 0 taken 6349 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1284 times.
✓ Branch 3 taken 5065 times.
6349 screen_handles[i] = {scr, special_warp_return_scrs[i].is_valid() ? &special_warp_return_scrs[i] : nullptr, screen, i};
6649
6650
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 907 times.
✗ Branch 3 not taken.
907 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
6651
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 toggle_gswitches_load(screen_handles);
6652
6653
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 902 times.
907 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6654 {
6655
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 remove_lockblocks(screen_handles);
6656 5 }
6657
6658
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 906 times.
907 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6659 {
6660
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6661 1 }
6662
6663
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mCHEST) // if special stuff done before
6664 {
6665 remove_chests(screen_handles);
6666 }
6667
6668
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6669 {
6670 remove_lockedchests(screen_handles);
6671 }
6672
6673
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6674 {
6675 remove_bosschests(screen_handles);
6676 }
6677
6678
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xdoors(screen_handles, true);
6679
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xstatecombos(screen_handles, true);
6680
6681 // check doors
6682
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✓ Branch 3 taken 371 times.
907 if (isdungeon(destdmap, screen))
6683 {
6684
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 371 times.
1855 for(int32_t i=0; i<4; i++)
6685 {
6686 1484 int32_t door=scr->door[i];
6687
6688
4/5
✓ Branch 0 taken 91 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 89 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1295 times.
1484 switch(door)
6689 {
6690 case d1WAYSHUTTER:
6691 case dSHUTTER:
6692 if ((ldir^1)==i && screen == home_screen)
6693 {
6694 scr->door[i]=dOPENSHUTTER;
6695 }
6696
6697 get_screen_state(screen).open_doors = -4;
6698 105 break;
6699
6700 case dLOCKED:
6701
3/4
✓ Branch 0 taken 91 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 80 times.
91 if(game->maps[mi]&(mDOOR_UP<<i))
6702 {
6703 80 scr->door[i]=dUNLOCKED;
6704 80 }
6705
6706 91 break;
6707
6708 case dBOSS:
6709
3/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 5 times.
9 if(game->maps[mi]&(mDOOR_UP<<i))
6710 {
6711 5 scr->door[i]=dOPENBOSS;
6712 5 }
6713
6714 9 break;
6715
6716 case dBOMB:
6717
3/4
✓ Branch 0 taken 89 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 51 times.
89 if(game->maps[mi]&(mDOOR_UP<<i))
6718 {
6719 51 scr->door[i]=dBOMBED;
6720 51 }
6721
6722 89 break;
6723 }
6724
6725
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 105 times.
1589 update_door(scr, i, scr->door[i]);
6726
6727
4/4
✓ Branch 0 taken 1390 times.
✓ Branch 1 taken 94 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 1379 times.
1484 if(door==dSHUTTER||door==d1WAYSHUTTER)
6728 {
6729 105 scr->door[i]=door;
6730 105 }
6731 1484 }
6732 371 }
6733
6734
2/2
✓ Branch 0 taken 6139 times.
✓ Branch 1 taken 1117 times.
7256 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6735 {
6736
4/4
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 697 times.
✓ Branch 2 taken 593 times.
✓ Branch 3 taken 4849 times.
6139 if (j<0 || scr->layermap[j] > 0)
6737 {
6738
4/4
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 907 times.
✓ Branch 2 taken 382 times.
✓ Branch 3 taken 1 times.
1290 mapscr *layerscreen= (j<0 ? scr : special_warp_return_scrs[j+1].valid ? &special_warp_return_scrs[j+1] :
6739 1 &TheMaps[(scr->layermap[j]-1)*MAPSCRS]+scr->layerscreen[j]);
6740
6741
2/2
✓ Branch 0 taken 226830 times.
✓ Branch 1 taken 1500 times.
228330 for(int32_t i=0; i<176; ++i)
6742 {
6743 226830 int32_t c=layerscreen->data[i];
6744
6745 // New screen flag: Cycle Combos At Screen Init
6746
5/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 226824 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 210 times.
✓ Branch 7 taken 210 times.
226830 if(combobuf[c].nextcombo != 0 && (scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6747 {
6748 210 int32_t r = 0;
6749
6750
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 210 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
210 while(combobuf[c].can_cycle() && r++ < 10)
6751 {
6752 newcombo const& cmb = combobuf[c];
6753 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6754 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6755 layerscreen->data[i] = cid;
6756 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6757 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6758 c = layerscreen->data[i];
6759 }
6760 }
6761 227040 }
6762 1500 }
6763 6349 }
6764 1537 }
6765
6766 // Load screen (and layers). Unlike loadscr, this doesn't load to the global temporary_screens, but
6767 // instead returns an array of mapscr.
6768 // Used to draw/save the map.
6769 47360 std::array<mapscr, 7> loadscr2(int32_t screen)
6770 {
6771 47360 std::array<mapscr, 7> scrs;
6772 47360 mapscr* scr = &scrs[0];
6773
6774
2/2
✓ Branch 0 taken 66834661 times.
✓ Branch 1 taken 47360 times.
66882021 for(word x=0; x<animated_combos; x++)
6775 {
6776
2/2
✓ Branch 0 taken 33899045 times.
✓ Branch 1 taken 32935616 times.
66834661 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6777 {
6778 32935616 combobuf[animated_combo_table4[x][0]].aclk=0;
6779 32935616 }
6780 66834661 }
6781
6782
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 const mapscr* source = get_canonical_scr(cur_map, screen);
6783
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 if (!source->is_valid())
6784 {
6785 scrs[0].valid = 0;
6786 return scrs;
6787 }
6788
6789
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 *scr = *get_canonical_scr(cur_map, screen);
6790
2/2
✓ Branch 0 taken 284160 times.
✓ Branch 1 taken 47360 times.
331520 for (int i = 1; i <= 6; i++)
6791 {
6792
2/2
✓ Branch 0 taken 209501 times.
✓ Branch 1 taken 74659 times.
284160 if (scr->layermap[i-1] > 0)
6793
2/4
✓ Branch 0 taken 74659 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 74659 times.
✗ Branch 3 not taken.
74659 scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6794 else
6795
2/4
✓ Branch 0 taken 209501 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 209501 times.
✗ Branch 3 not taken.
209501 scrs[i] = {};
6796 284160 }
6797
6798 screen_handles_t screen_handles;
6799
2/2
✓ Branch 0 taken 47360 times.
✓ Branch 1 taken 331520 times.
378880 for (int i = 0; i < 7; i++)
6800
3/4
✓ Branch 0 taken 331520 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 114582 times.
✓ Branch 3 taken 216938 times.
331520 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
6801
6802 47360 int mi = mapind(cur_map, screen);
6803
6804
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47306 times.
✓ Branch 3 taken 54 times.
47360 if(canPermSecret(-1,screen))
6805 {
6806
3/4
✓ Branch 0 taken 47306 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6344 times.
✓ Branch 3 taken 40962 times.
47306 if(game->maps[mi]&mSECRET) // if special stuff done before
6807 {
6808
1/2
✓ Branch 0 taken 6344 times.
✗ Branch 1 not taken.
6344 reveal_hidden_stairs(scr, screen, false);
6809 6344 bool from_active_screen = false;
6810 6344 bool do_replay_comment = true;
6811
1/2
✓ Branch 0 taken 6344 times.
✗ Branch 1 not taken.
6344 trigger_secrets_for_screen_internal(screen_handles, from_active_screen, false, -1, do_replay_comment);
6812 6344 }
6813
3/4
✓ Branch 0 taken 47306 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47289 times.
✓ Branch 3 taken 17 times.
47306 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6814 {
6815
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 17 times.
136 for (int layer = 0; layer <= 6; layer++)
6816 {
6817 119 mapscr* tscr = &scrs[layer];
6818
2/2
✓ Branch 0 taken 20944 times.
✓ Branch 1 taken 119 times.
21063 for (int pos = 0; pos < 176; pos++)
6819 {
6820 20944 newcombo const* cmb = &combobuf[tscr->data[pos]];
6821
2/2
✓ Branch 0 taken 20927 times.
✓ Branch 1 taken 17 times.
20944 if(cmb->type == cLIGHTTARGET)
6822 {
6823
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if(!(cmb->usrflags&cflag1)) //Unlit version
6824 {
6825 17 tscr->data[pos] += 1;
6826 17 }
6827 17 }
6828 20944 }
6829 119 }
6830 17 }
6831 47306 }
6832
6833
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 271 times.
✓ Branch 3 taken 47089 times.
47360 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6834 {
6835
1/2
✓ Branch 0 taken 271 times.
✗ Branch 1 not taken.
271 remove_lockblocks(screen_handles);
6836 271 }
6837
6838
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 47359 times.
47360 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6839 {
6840
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6841 1 }
6842
6843
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 106 times.
✓ Branch 3 taken 47254 times.
47360 if(game->maps[mi]&mCHEST) // if special stuff done before
6844 {
6845
1/2
✓ Branch 0 taken 106 times.
✗ Branch 1 not taken.
106 remove_chests(screen_handles);
6846 106 }
6847
6848
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 47336 times.
47360 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6849 {
6850
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 remove_lockedchests(screen_handles);
6851 24 }
6852
6853
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 47360 times.
47360 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6854 {
6855 remove_bosschests(screen_handles);
6856 }
6857
6858
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 clear_xdoors(screen_handles);
6859
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 clear_xstatecombos(screen_handles);
6860
6861 // check doors
6862
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47306 times.
✓ Branch 3 taken 54 times.
47360 if (isdungeon(screen))
6863 {
6864
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 54 times.
270 for(int32_t i=0; i<4; i++)
6865 {
6866 216 int32_t door=scr->door[i];
6867 216 bool putit=true;
6868
6869
4/5
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 61 times.
✓ Branch 4 taken 139 times.
216 switch(door)
6870 {
6871 case d1WAYSHUTTER:
6872 case dSHUTTER:
6873 61 break;
6874
6875 case dLOCKED:
6876
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 if(game->maps[mi]&(mDOOR_UP<<i))
6877 {
6878 12 scr->door[i]=dUNLOCKED;
6879 12 }
6880
6881 12 break;
6882
6883 case dBOSS:
6884
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 if(game->maps[mi]&(mDOOR_UP<<i))
6885 {
6886 scr->door[i]=dOPENBOSS;
6887 }
6888
6889 4 break;
6890
6891 case dBOMB:
6892 if(game->maps[mi]&(mDOOR_UP<<i))
6893 {
6894 scr->door[i]=dBOMBED;
6895 }
6896
6897 break;
6898 }
6899
6900
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
216 if(putit)
6901 {
6902
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 putdoor(scr, scrollbuf, i, scr->door[i], false);
6903 216 }
6904
6905
3/4
✓ Branch 0 taken 155 times.
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 155 times.
216 if(door==dSHUTTER||door==d1WAYSHUTTER)
6906 {
6907 61 scr->door[i]=door;
6908 61 }
6909 216 }
6910 54 }
6911
6912
2/2
✓ Branch 0 taken 331520 times.
✓ Branch 1 taken 47360 times.
378880 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6913 {
6914
4/4
✓ Branch 0 taken 284160 times.
✓ Branch 1 taken 47360 times.
✓ Branch 2 taken 74659 times.
✓ Branch 3 taken 209501 times.
331520 if (j < 0 || scr->layermap[j] > 0)
6915 {
6916
2/2
✓ Branch 0 taken 74659 times.
✓ Branch 1 taken 47360 times.
122019 mapscr *layerscreen= (j<0 ? scr
6917 74659 : &(TheMaps[(scr->layermap[j]-1)*MAPSCRS+scr->layerscreen[j]]));
6918
6919
2/2
✓ Branch 0 taken 21475344 times.
✓ Branch 1 taken 122019 times.
21597363 for(int32_t i=0; i<176; ++i)
6920 {
6921 21475344 int32_t c=layerscreen->data[i];
6922
6923 // New screen flag: Cycle Combos At Screen Init
6924
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 21475344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
21475344 if((scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6925 {
6926 int32_t r = 0;
6927
6928 while(combobuf[c].can_cycle() && r++ < 10)
6929 {
6930 newcombo const& cmb = combobuf[c];
6931 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6932 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6933 layerscreen->data[i] = cid;
6934 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6935 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6936 c = layerscreen->data[i];
6937 }
6938 }
6939 21475344 }
6940 122019 }
6941 331520 }
6942
6943 47360 return scrs;
6944
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 }
6945
6946 19767692 void putscr(mapscr* scr, BITMAP* dest, int32_t x, int32_t y)
6947 {
6948 // This is a bogus value while screenscrolling == true, but that's ok
6949 // because it is only used to calculate the rpos, and during screenscrolling
6950 // only the modulus to get pos (draw_cmb_pos does RPOS_TO_POS) is needed, which
6951 // is always the same no matter the value of scr.
6952 19767692 int screen = get_screen_for_world_xy(x, y);
6953
6954 19767692 x -= viewport.x;
6955 19767692 y -= viewport.y;
6956
6957
3/6
✓ Branch 0 taken 19767692 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19767692 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 19767692 times.
19767692 if (!scr->is_valid()||!show_layers[0]||scr->hidelayers & 1)
6958 {
6959 rectfill(dest,x,y,x+255,y+175,0);
6960 return;
6961 }
6962
6963 39387917 bool over = XOR(scr->flags7&fLAYER2BG,DMaps[cur_dmap].flags&dmfLAYER2BG)
6964
2/2
✓ Branch 0 taken 19620225 times.
✓ Branch 1 taken 147467 times.
19767692 || XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)
6965
2/2
✓ Branch 0 taken 243651 times.
✓ Branch 1 taken 19376574 times.
19620225 || !get_qr(qr_CLASSIC_DRAWING_ORDER);
6966
6967 int start_x, end_x, start_y, end_y;
6968 19767692 get_bounds_for_draw_cmb_calls(dest, x, y, start_x, end_x, start_y, end_y);
6969
2/2
✓ Branch 0 taken 19767692 times.
✓ Branch 1 taken 210543286 times.
230310978 for (int cy = start_y; cy < end_y; cy++)
6970 {
6971
2/2
✓ Branch 0 taken 3196690802 times.
✓ Branch 1 taken 210543286 times.
3407234088 for (int cx = start_x; cx < end_x; cx++)
6972 {
6973 3196690802 int i = cx + cy*16;
6974
2/2
✓ Branch 0 taken 374288294 times.
✓ Branch 1 taken 2822402508 times.
3196690802 auto rpos = screenscrolling ? rpos_t::None : POS_TO_RPOS(i, screen);
6975 3196690802 draw_cmb_pos(dest, x + cx*16, y + cy*16, rpos, scr->data[i], scr->cset[i], 0, over, false);
6976 3196690802 }
6977 210543286 }
6978 19767692 }
6979
6980 16133788 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y)
6981 {
6982
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16133788 times.
16133788 if (!show_layers[0])
6983 {
6984 return;
6985 }
6986
6987 16133788 x -= viewport.x;
6988 16133788 y -= viewport.y;
6989
6990
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16133788 times.
32403894 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
6991 16270106 mapscr* scr = screen_handles[0].base_scr;
6992
1/2
✓ Branch 0 taken 16270106 times.
✗ Branch 1 not taken.
16270106 if (!scr->is_valid())
6993 return;
6994
6995
2/2
✓ Branch 0 taken 123411 times.
✓ Branch 1 taken 16146695 times.
16270106 if(scr->door[0]==dBOMBED)
6996 {
6997 123411 over_door(scr, dest, 39, up, offx+x, offy+y);
6998 123411 }
6999
7000
2/2
✓ Branch 0 taken 143109 times.
✓ Branch 1 taken 16126997 times.
16270106 if(scr->door[1]==dBOMBED)
7001 {
7002 143109 over_door(scr, dest, 135, down, offx+x, offy+y);
7003 143109 }
7004
7005
2/2
✓ Branch 0 taken 155862 times.
✓ Branch 1 taken 16114244 times.
16270106 if(scr->door[2]==dBOMBED)
7006 {
7007 155862 over_door(scr, dest, 66, left, offx+x, offy+y);
7008 155862 }
7009
7010
2/2
✓ Branch 0 taken 132289 times.
✓ Branch 1 taken 16137817 times.
16270106 if(scr->door[3]==dBOMBED)
7011 {
7012 132289 over_door(scr, dest, 77, right, offx+x, offy+y);
7013 132289 }
7014 16270106 });
7015 16133788 }
7016
7017 3497586 void putscrdoors(mapscr* scr, BITMAP *dest, int32_t x, int32_t y)
7018 {
7019
2/4
✓ Branch 0 taken 3497586 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3497586 times.
✗ Branch 3 not taken.
3497586 if (!scr->is_valid() || !show_layers[0])
7020 return;
7021
7022 3497586 x -= viewport.x;
7023 3497586 y -= viewport.y;
7024
7025
2/2
✓ Branch 0 taken 37656 times.
✓ Branch 1 taken 3459930 times.
3497586 if(scr->door[0]==dBOMBED)
7026 {
7027 37656 over_door(scr,dest,39,up,x,y);
7028 37656 }
7029
7030
2/2
✓ Branch 0 taken 36495 times.
✓ Branch 1 taken 3461091 times.
3497586 if(scr->door[1]==dBOMBED)
7031 {
7032 36495 over_door(scr,dest,135,down,x,y);
7033 36495 }
7034
7035
2/2
✓ Branch 0 taken 40440 times.
✓ Branch 1 taken 3457146 times.
3497586 if(scr->door[2]==dBOMBED)
7036 {
7037 40440 over_door(scr,dest,66,left,x,y);
7038 40440 }
7039
7040
2/2
✓ Branch 0 taken 37063 times.
✓ Branch 1 taken 3460523 times.
3497586 if(scr->door[3]==dBOMBED)
7041 {
7042 37063 over_door(scr,dest,77,right,x,y);
7043 37063 }
7044 3497586 }
7045 262959708 static inline bool standing_on_z(newcombo const& cmb, zfix const& standing_z_state)
7046 {
7047
1/2
✓ Branch 0 taken 262959708 times.
✗ Branch 1 not taken.
262959708 if (cmb.dive_under_level)
7048 {
7049 if (standing_z_state <= -cmb.dive_under_level)
7050 return true;
7051 }
7052
7053 262959708 zfix cmb_z, cmb_z_step;
7054
4/4
✓ Branch 0 taken 92789 times.
✓ Branch 1 taken 262866919 times.
✓ Branch 2 taken 88819 times.
✓ Branch 3 taken 3970 times.
262959708 if(cmb.type == cCSWITCHBLOCK && (cmb.usrflags & cflag9))
7055 {
7056 3970 cmb_z = cmb.c_attributes[2];
7057
1/2
✓ Branch 0 taken 3970 times.
✗ Branch 1 not taken.
3970 cmb_z_step = zc_max(0_zf,cmb.c_attributes[3]);
7058 3970 }
7059
2/2
✓ Branch 0 taken 1983 times.
✓ Branch 1 taken 262953755 times.
262955738 else if(cmb.genflags & cflag3)
7060 {
7061 1983 cmb_z = cmb.z_height;
7062
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1983 times.
1983 cmb_z_step = zc_max(0_zf,cmb.z_step_height);
7063 1983 }
7064 262953755 else return false;
7065
7066
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5953 times.
5953 if (standing_z_state == STANDING_Z_MAX) // 'infinity'
7067 return true;
7068
2/2
✓ Branch 0 taken 1149 times.
✓ Branch 1 taken 4804 times.
5953 if (!cmb_z) return false; // infinite height
7069
7070 4804 return (cmb_z - cmb_z_step) <= standing_z_state;
7071 262959708 }
7072 62156035 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt)
7073 {
7074 62156035 return _walkflag(zx,zy,cnt,0_zf);
7075 }
7076
7077 142618264 bool _walkflag_new(const mapscr* s0, const mapscr* s1, const mapscr* s2, zfix_round zx, zfix_round zy, zfix const& standing_z_state, bool is_temp_screens)
7078 {
7079 142618264 int x = zx.getRound(), y = zy.getRound();
7080 142618264 int pos = COMBOPOS(x % 256, y % 176);
7081 142618264 const newcombo& c = combobuf[s0->data[pos]];
7082 142618264 const newcombo& c1 = combobuf[s1->data[pos]];
7083 142618264 const newcombo& c2 = combobuf[s2->data[pos]];
7084
4/4
✓ Branch 0 taken 140526638 times.
✓ Branch 1 taken 2091626 times.
✓ Branch 2 taken 140517178 times.
✓ Branch 3 taken 9460 times.
285466518 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
7085
4/4
✓ Branch 0 taken 114995 times.
✓ Branch 1 taken 140632173 times.
✓ Branch 2 taken 2211836 times.
✓ Branch 3 taken 4245 times.
142618264 (iswater_type(c2.type))) && DRIEDLAKE);
7086 142848254 int32_t b=1;
7087
2/2
✓ Branch 0 taken 70427742 times.
✓ Branch 1 taken 72420512 times.
142848254 if(x&8) b<<=2;
7088
2/2
✓ Branch 0 taken 66774572 times.
✓ Branch 1 taken 76073682 times.
142848254 if(y&8) b<<=1;
7089
7090 142848254 int32_t cwalkflag = c.walk;
7091
4/4
✓ Branch 0 taken 142733250 times.
✓ Branch 1 taken 115004 times.
✓ Branch 2 taken 142733086 times.
✓ Branch 3 taken 164 times.
142848254 if(is_temp_screens && standing_on_z(c,standing_z_state)) cwalkflag &= (c.walk>>4)^0xF;
7092
8/10
✓ Branch 0 taken 57502 times.
✓ Branch 1 taken 142790588 times.
✓ Branch 2 taken 2206612 times.
✓ Branch 3 taken 2149110 times.
✓ Branch 4 taken 2206612 times.
✓ Branch 5 taken 142733086 times.
✓ Branch 6 taken 2206612 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2206612 times.
✗ Branch 9 not taken.
142848090 else if ((c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) || (iswater_type(c.type) && ((c.walk>>4)&b) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
7093
2/2
✓ Branch 0 taken 63216283 times.
✓ Branch 1 taken 79516967 times.
142733250 if (s1 != s0)
7094 {
7095
3/4
✓ Branch 0 taken 79516967 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 79516349 times.
✓ Branch 3 taken 618 times.
79516967 if(is_temp_screens && standing_on_z(c1,standing_z_state)) cwalkflag &= (c1.walk>>4)^0xF;
7096
4/10
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 79504620 times.
✓ Branch 2 taken 11729 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11729 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
79516349 else if ((iswater_type(c1.type) && ((c1.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_1) && !((c1.usrflags&cflag3) || (c1.usrflags&cflag4)))) cwalkflag &= c1.walk;
7097
2/2
✓ Branch 0 taken 71255 times.
✓ Branch 1 taken 79445094 times.
79516349 else if (c1.type == cBRIDGE)
7098 {
7099
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 71255 times.
71255 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
7100 {
7101 71255 int efflag = (c1.walk & 0xF0)>>4;
7102 71255 int newsolid = (c1.walk & 0xF);
7103 71255 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
7104 71255 }
7105 else cwalkflag &= c1.walk;
7106 71255 }
7107
3/8
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 79433365 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11729 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
79445094 else if ((iswater_type(c1.type) && get_qr(qr_WATER_ON_LAYER_1) && ((c1.usrflags&cflag3) || (c1.usrflags&cflag4)) && ((c1.walk>>4)&b))) cwalkflag = 0;
7108 79445094 else cwalkflag |= c1.walk;
7109 79516967 }
7110
2/2
✓ Branch 0 taken 102023759 times.
✓ Branch 1 taken 40709491 times.
142733250 if (s2 != s0)
7111 {
7112
2/4
✓ Branch 0 taken 40709491 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40709491 times.
✗ Branch 3 not taken.
40709491 if(is_temp_screens && standing_on_z(c2,standing_z_state)) cwalkflag &= (c2.walk>>4)^0xF;
7113
7/10
✓ Branch 0 taken 5889 times.
✓ Branch 1 taken 40703602 times.
✓ Branch 2 taken 5889 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3735 times.
✓ Branch 5 taken 2154 times.
✓ Branch 6 taken 3735 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 3735 times.
40709491 else if ((iswater_type(c2.type) && ((c2.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_2) && !((c2.usrflags&cflag3) || (c2.usrflags&cflag4)))) cwalkflag &= c2.walk;
7114
2/2
✓ Branch 0 taken 16725 times.
✓ Branch 1 taken 40689031 times.
40705756 else if (c2.type == cBRIDGE)
7115 {
7116
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16725 times.
16725 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
7117 {
7118 16725 int efflag = (c2.walk & 0xF0)>>4;
7119 16725 int newsolid = (c2.walk & 0xF);
7120 16725 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
7121 16725 }
7122 else cwalkflag &= c2.walk;
7123 16725 }
7124
3/8
✓ Branch 0 taken 2154 times.
✓ Branch 1 taken 40686877 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2154 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
40689031 else if ((iswater_type(c2.type) && get_qr(qr_WATER_ON_LAYER_2) && ((c2.usrflags&cflag3) || (c2.usrflags&cflag4))) && ((c2.walk>>4)&b)) cwalkflag = 0;
7125 40689031 else cwalkflag |= c2.walk;
7126 40709491 }
7127
7128
4/4
✓ Branch 0 taken 30808240 times.
✓ Branch 1 taken 111925010 times.
✓ Branch 2 taken 948 times.
✓ Branch 3 taken 30807292 times.
142733250 if((cwalkflag&b) && !dried)
7129 30807292 return true;
7130
7131
3/4
✓ Branch 0 taken 111925958 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 111856768 times.
✓ Branch 3 taken 69190 times.
111925958 if (is_temp_screens && collide_object(zx, zy, 0.0001_zf, 0.0001_zf)) return true;
7132
7133 111856768 return false;
7134 142733250 }
7135
7136 // Returns true if the combo at viewport position x,y is solid. Looks at a combo's quadrant walkablity flags.
7137 142733250 static bool _walkflag_new(zfix_round zx, zfix_round zy, zfix const& standing_z_state)
7138 {
7139 142733250 int x = zx.getRound(), y = zy.getRound();
7140 142733250 mapscr* s0 = get_scr_for_world_xy_layer(x, y, 0);
7141 142733250 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
7142 142733250 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
7143
2/2
✓ Branch 0 taken 63216283 times.
✓ Branch 1 taken 79516967 times.
142733250 if (!s1->valid) s1 = s0;
7144
2/2
✓ Branch 0 taken 102023759 times.
✓ Branch 1 taken 40709491 times.
142733250 if (!s2->valid) s2 = s0;
7145 142733250 return _walkflag_new(s0, s1, s2, zx, zy, standing_z_state, true);
7146 }
7147
7148 138205373 bool _walkflag(zfix_round x,zfix_round y,int32_t cnt,zfix const& standing_z_state)
7149 {
7150 138205373 int max_x = world_w;
7151 138205373 int max_y = world_h;
7152
2/2
✓ Branch 0 taken 78162636 times.
✓ Branch 1 taken 60042737 times.
138205373 if (!get_qr(qr_LTTPWALK))
7153 {
7154 60042737 max_x -= 7;
7155 60042737 max_y -= 7;
7156 60042737 }
7157
4/4
✓ Branch 0 taken 137933005 times.
✓ Branch 1 taken 272368 times.
✓ Branch 2 taken 83268 times.
✓ Branch 3 taken 137849737 times.
138205373 if (x < 0 || y < 0) return false;
7158
2/2
✓ Branch 0 taken 323548 times.
✓ Branch 1 taken 137526189 times.
137849737 if (x >= max_x) return false;
7159
3/4
✓ Branch 0 taken 571808 times.
✓ Branch 1 taken 136954381 times.
✓ Branch 2 taken 571808 times.
✗ Branch 3 not taken.
137526189 if (x >= max_x - 8 && cnt == 2) return false;
7160
2/2
✓ Branch 0 taken 136971926 times.
✓ Branch 1 taken 554263 times.
137526189 if (y >= max_y) return false;
7161
7162
4/4
✓ Branch 0 taken 30758247 times.
✓ Branch 1 taken 106213679 times.
✓ Branch 2 taken 100452355 times.
✓ Branch 3 taken 5761324 times.
136971926 return _walkflag_new(x, y, standing_z_state) || (cnt != 1 && _walkflag_new(x + 8, y, standing_z_state));
7163 138205373 }
7164
7165 105156080 static bool effectflag(int32_t x, int32_t y, int32_t layer)
7166 {
7167 105156080 mapscr* s0 = get_scr_for_world_xy(x, y);
7168 105156080 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
7169 105156080 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
7170
2/2
✓ Branch 0 taken 57657645 times.
✓ Branch 1 taken 47498435 times.
105156080 if (!s1->valid) s1 = s0;
7171
2/2
✓ Branch 0 taken 24624446 times.
✓ Branch 1 taken 80531634 times.
105156080 if (!s2->valid) s2 = s0;
7172
7173 105156080 int pos = COMBOPOS(x % 256, y % 176);
7174 105156080 const newcombo& c = combobuf[s0->data[pos]];
7175 105156080 const newcombo& c1 = combobuf[s1->data[pos]];
7176 105156080 const newcombo& c2 = combobuf[s2->data[pos]];
7177
4/4
✓ Branch 0 taken 104160376 times.
✓ Branch 1 taken 995704 times.
✓ Branch 2 taken 104159096 times.
✓ Branch 3 taken 1280 times.
210312160 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
7178
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 104159096 times.
✓ Branch 2 taken 995300 times.
✓ Branch 3 taken 1684 times.
105156080 (iswater_type(c2.type))) && DRIEDLAKE);
7179 105156080 int32_t b=1;
7180
2/2
✓ Branch 0 taken 53215841 times.
✓ Branch 1 taken 51940239 times.
105156080 if(x&8) b<<=2;
7181
2/2
✓ Branch 0 taken 44692803 times.
✓ Branch 1 taken 60463277 times.
105156080 if(y&8) b<<=1;
7182
7183 105156080 int32_t cwalkflag = (c.walk>>4);
7184
2/2
✓ Branch 0 taken 80385401 times.
✓ Branch 1 taken 24770679 times.
105156080 if (layer == 0) cwalkflag = (c1.walk>>4);
7185
2/2
✓ Branch 0 taken 80387077 times.
✓ Branch 1 taken 24769003 times.
105156080 if (layer == 1) cwalkflag = (c2.walk>>4);
7186 //if (c.type == cBRIDGE || (iswater_type(c.type) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
7187
4/4
✓ Branch 0 taken 57657645 times.
✓ Branch 1 taken 47498435 times.
✓ Branch 2 taken 24572336 times.
✓ Branch 3 taken 33085309 times.
105156080 if (s1 != s0 && layer < 0)
7188 {
7189
2/2
✓ Branch 0 taken 24556122 times.
✓ Branch 1 taken 16214 times.
24572336 if (c1.type == cBRIDGE) cwalkflag &= (~(c1.walk>>4));
7190 24572336 }
7191
4/4
✓ Branch 0 taken 24624446 times.
✓ Branch 1 taken 80531634 times.
✓ Branch 2 taken 17774749 times.
✓ Branch 3 taken 6849697 times.
105156080 if (s2 != s0 && layer < 1)
7192 {
7193
2/2
✓ Branch 0 taken 17762865 times.
✓ Branch 1 taken 11884 times.
17774749 if (c2.type == cBRIDGE) cwalkflag &= (~(c2.walk>>4));
7194 17774749 }
7195
7196
2/2
✓ Branch 0 taken 104978076 times.
✓ Branch 1 taken 178004 times.
105156080 return (cwalkflag&b) ? !dried : false;
7197 }
7198
7199 105529404 bool _effectflag(int32_t x,int32_t y,int32_t cnt, int32_t layer, bool notLink)
7200 {
7201 DCHECK(cnt == 0 || cnt == 1);
7202 105529404 int max_x = world_w;
7203 105529404 int max_y = world_h;
7204
3/4
✓ Branch 0 taken 45833723 times.
✓ Branch 1 taken 59695681 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45833723 times.
105529404 if (!get_qr(qr_LTTPWALK) && !notLink)
7205 {
7206 45833723 max_x -= 7;
7207 45833723 max_y -= 7;
7208 45833723 }
7209
4/4
✓ Branch 0 taken 105528652 times.
✓ Branch 1 taken 752 times.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 105528448 times.
105529404 if (x < 0 || y < 0) return false;
7210
2/2
✓ Branch 0 taken 816 times.
✓ Branch 1 taken 105527632 times.
105528448 if (x >= max_x) return false;
7211
3/4
✓ Branch 0 taken 526426 times.
✓ Branch 1 taken 105001206 times.
✓ Branch 2 taken 526426 times.
✗ Branch 3 not taken.
105527632 if (x >= max_x - 8 && cnt == 2) return false;
7212
2/2
✓ Branch 0 taken 371552 times.
✓ Branch 1 taken 105156080 times.
105527632 if (y >= max_y) return false;
7213
7214
3/4
✓ Branch 0 taken 104977286 times.
✓ Branch 1 taken 178794 times.
✓ Branch 2 taken 178794 times.
✗ Branch 3 not taken.
105156080 return effectflag(x, y, layer) || (cnt == 2 && effectflag(x + 8, y, layer));
7215 105529404 }
7216
7217 // used by mapdata->isSolid(x,y) in ZScript
7218 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7219 {
7220 int x = zx.getRound(), y = zy.getRound();
7221 {
7222 int max_x = 256;
7223 int max_y = 176;
7224 if (!get_qr(qr_LTTPWALK))
7225 {
7226 max_x -= 7;
7227 max_y -= 7;
7228 }
7229 if (x < 0 || y < 0) return false;
7230 if (x >= max_x) return false;
7231 if (x >= max_x - 8 && cnt == 2) return false;
7232 if (y >= max_y) return false;
7233 }
7234
7235 const mapscr *s1, *s2;
7236 s1 = s2 = m;
7237
7238 if ( m->layermap[0] > 0 && m->layermap[0] <= map_count )
7239 {
7240 const mapscr* s = get_canonical_scr(m->layermap[0] - 1, m->layerscreen[0]);
7241 if (s->is_valid())
7242 s1 = s;
7243 }
7244
7245 if ( m->layermap[1] > 0 && m->layermap[1] <= map_count )
7246 {
7247 const mapscr* s = get_canonical_scr(m->layermap[1] - 1, m->layerscreen[1]);
7248 if (s->is_valid())
7249 s2 = s;
7250 }
7251
7252 zfix unused;
7253 return _walkflag_new(m, s1, s2, x, y, unused, false) || (cnt != 1 && _walkflag_new(m, s1, s2, x + 8, y, unused, false));
7254 }
7255
7256 bool _walkflag_layer(zfix_round x, zfix_round y, int32_t layer, int32_t cnt)
7257 {
7258 DCHECK_LAYER_NEG1_INDEX(layer);
7259 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7260 if (!m->is_valid()) return false;
7261 return _walkflag_layer(x, y, cnt, m);
7262 }
7263
7264 static bool _walkflag_layer_new(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m, int max_x, int max_y)
7265 {
7266 int x = zx.getRound(), y = zy.getRound();
7267
7268 if (!get_qr(qr_LTTPWALK))
7269 {
7270 max_x -= 7;
7271 max_y -= 7;
7272 }
7273 if (x < 0 || y < 0) return false;
7274 if (x >= max_x) return false;
7275 if (x >= max_x - 8 && cnt == 2) return false;
7276 if (y >= max_y) return false;
7277
7278 if(!m) return true;
7279
7280 int pos = COMBOPOS(x%256, y%176);
7281 const newcombo* c = &combobuf[m->data[pos]];
7282 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7283 int32_t b=1;
7284
7285 if(x&8) b<<=2;
7286
7287 if(y&8) b<<=1;
7288
7289 if((c->walk&b) && !dried)
7290 return true;
7291
7292 if(cnt==1) return false;
7293
7294 ++pos;
7295
7296 if(!(x&8))
7297 b<<=2;
7298 else
7299 {
7300 c = &combobuf[m->data[pos]];
7301 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7302 b=1;
7303
7304 if(y&8) b<<=1;
7305 }
7306
7307 return (c->walk&b) ? !dried : false;
7308 }
7309
7310 //Only check the given mapscr*, not its layer 1&2
7311 bool _walkflag_layer(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7312 {
7313 return _walkflag_layer_new(zx, zy, cnt, m, world_w, world_h);
7314 }
7315
7316 bool _walkflag_layer_scrolling(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7317 {
7318 return _walkflag_layer_new(zx, zy, cnt, m, scrolling_region.width, scrolling_region.height);
7319 }
7320
7321 447249 bool _effectflag_layer(int32_t x, int32_t y, int32_t layer, int32_t cnt, bool notLink)
7322 {
7323 DCHECK_LAYER_NEG1_INDEX(layer);
7324 447249 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7325
2/2
✓ Branch 0 taken 1762 times.
✓ Branch 1 taken 445487 times.
447249 if (!m->is_valid()) return false;
7326 445487 return _effectflag_layer(x, y, cnt, m, notLink);
7327 447249 }
7328
7329 518564 bool _effectflag_layer(int32_t x,int32_t y,int32_t cnt, mapscr* m, bool notLink)
7330 {
7331 518564 int max_x = world_w;
7332 518564 int max_y = world_h;
7333
3/4
✓ Branch 0 taken 50002 times.
✓ Branch 1 taken 468562 times.
✓ Branch 2 taken 50002 times.
✗ Branch 3 not taken.
518564 if (!get_qr(qr_LTTPWALK) && !notLink)
7334 {
7335 max_x -= 7;
7336 max_y -= 7;
7337 }
7338
2/4
✓ Branch 0 taken 518564 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 518564 times.
518564 if (x < 0 || y < 0) return false;
7339
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 518564 times.
518564 if (x >= max_x) return false;
7340
3/4
✓ Branch 0 taken 1342 times.
✓ Branch 1 taken 517222 times.
✓ Branch 2 taken 1342 times.
✗ Branch 3 not taken.
518564 if (x >= max_x - 8 && cnt == 2) return false;
7341
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 518564 times.
518564 if (y >= max_y) return false;
7342
7343
1/2
✓ Branch 0 taken 518564 times.
✗ Branch 1 not taken.
518564 if (!m) return true;
7344
7345 518564 int pos = COMBOPOS(x%256, y%176);
7346 518564 const newcombo* c = &combobuf[m->data[pos]];
7347
3/4
✓ Branch 0 taken 518164 times.
✓ Branch 1 taken 400 times.
✓ Branch 2 taken 400 times.
✗ Branch 3 not taken.
518964 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7348 518564 int32_t b=1;
7349
7350
2/2
✓ Branch 0 taken 275506 times.
✓ Branch 1 taken 243058 times.
518564 if(x&8) b<<=2;
7351
7352
2/2
✓ Branch 0 taken 221968 times.
✓ Branch 1 taken 296596 times.
518564 if(y&8) b<<=1;
7353
7354
3/4
✓ Branch 0 taken 449575 times.
✓ Branch 1 taken 68989 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 449575 times.
518564 if(((c->walk>>4)&b) && !dried)
7355 449575 return true;
7356
7357
1/2
✓ Branch 0 taken 68989 times.
✗ Branch 1 not taken.
68989 if(cnt==1) return false;
7358
7359 ++pos;
7360
7361 if(!(x&8))
7362 b<<=2;
7363 else
7364 {
7365 c = &combobuf[m->data[pos]];
7366 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7367 b=1;
7368
7369 if(y&8) b<<=1;
7370 }
7371
7372 return ((c->walk>>4)&b) ? !dried : false;
7373 518564 }
7374
7375 860420 bool water_walkflag(int32_t x, int32_t y, int32_t cnt)
7376 {
7377 860420 int max_x = world_w;
7378 860420 int max_y = world_h;
7379
2/2
✓ Branch 0 taken 165182 times.
✓ Branch 1 taken 695238 times.
860420 if (!get_qr(qr_LTTPWALK))
7380 {
7381 695238 max_x -= 7;
7382 695238 max_y -= 7;
7383 695238 }
7384
2/4
✓ Branch 0 taken 860420 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 860420 times.
860420 if (x < 0 || y < 0) return false;
7385
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
860420 if (x >= max_x) return false;
7386
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
860420 if (x >= max_x - 8 && cnt == 2) return false;
7387
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
860420 if (y >= max_y) return false;
7388
7389
3/4
✓ Branch 0 taken 17860 times.
✓ Branch 1 taken 842560 times.
✓ Branch 2 taken 842560 times.
✗ Branch 3 not taken.
860420 return water_walkflag(x, y) || (cnt != 1 && water_walkflag(x + 8, y));
7390 860420 }
7391
7392 860420 bool water_walkflag(int32_t x, int32_t y)
7393 {
7394 860420 const newcombo& c = combobuf[MAPCOMBO2(-1, x, y)];
7395 860420 const newcombo& c1 = combobuf[MAPCOMBO2(0, x, y)];
7396 860420 const newcombo& c2 = combobuf[MAPCOMBO2(1, x, y)];
7397
7398 860420 int32_t b=1;
7399
2/2
✓ Branch 0 taken 439102 times.
✓ Branch 1 taken 421318 times.
860420 if(x&8) b<<=2;
7400
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
860420 if(y&8) b<<=1;
7401
7402
2/2
✓ Branch 0 taken 74192 times.
✓ Branch 1 taken 786228 times.
860420 if(get_qr(qr_NO_SOLID_SWIM))
7403 {
7404
2/2
✓ Branch 0 taken 474 times.
✓ Branch 1 taken 73718 times.
74192 if(c.walk&b)
7405 474 return true;
7406
7407
2/2
✓ Branch 0 taken 914 times.
✓ Branch 1 taken 72804 times.
73718 if(c1.walk&b)
7408 914 return true;
7409
7410
2/2
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 72733 times.
72804 if(c2.walk&b)
7411 71 return true;
7412 72733 }
7413 else
7414 {
7415
4/4
✓ Branch 0 taken 36133 times.
✓ Branch 1 taken 750095 times.
✓ Branch 2 taken 19762 times.
✓ Branch 3 taken 16371 times.
786228 if((c.walk&b) && !iswater_type(c.type))
7416 16371 return true;
7417
7418
3/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 769840 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
769857 if((c1.walk&b) && !iswater_type(c1.type))
7419 17 return true;
7420
7421
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 769827 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
769840 if((c2.walk&b) && !iswater_type(c2.type))
7422 13 return true;
7423 }
7424
7425 842560 return false;
7426 860420 }
7427
7428 589885 bool hit_walkflag(int32_t x,int32_t y,int32_t cnt)
7429 {
7430
2/2
✓ Branch 0 taken 100391 times.
✓ Branch 1 taken 489494 times.
589885 if(dlevel)
7431
8/8
✓ Branch 0 taken 488049 times.
✓ Branch 1 taken 1445 times.
✓ Branch 2 taken 484722 times.
✓ Branch 3 taken 3327 times.
✓ Branch 4 taken 483005 times.
✓ Branch 5 taken 1717 times.
✓ Branch 6 taken 4386 times.
✓ Branch 7 taken 478619 times.
489494 if(x<32 || y<40 || (x+(cnt-1)*8)>=world_w-32 || y>=world_h-32)
7432 10875 return true;
7433
7434
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 579008 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
579010 if(blockpath && y<((get_qr(qr_LTTPCOLLISION))?80:88))
7435 return true;
7436
7437
8/8
✓ Branch 0 taken 578724 times.
✓ Branch 1 taken 286 times.
✓ Branch 2 taken 578481 times.
✓ Branch 3 taken 243 times.
✓ Branch 4 taken 578270 times.
✓ Branch 5 taken 211 times.
✓ Branch 6 taken 396 times.
✓ Branch 7 taken 577874 times.
579010 if(x<16 || y<16 || (x+(cnt-1)*8)>=world_w-16 || y>=world_h-16)
7438 1136 return true;
7439
7440 // for(int32_t i=0; i<4; i++)
7441
4/4
✓ Branch 0 taken 841 times.
✓ Branch 1 taken 577033 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 805 times.
577874 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7442 36 return true;
7443
7444
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 577837 times.
577838 if (collide_object(x, y,cnt*8, 1))
7445 1 return true;
7446
7447 577837 return _walkflag(x,y,cnt);
7448 589885 }
7449
7450 12220 bool solpush_walkflag(int32_t x, int32_t y, int32_t cnt, solid_object const* ign)
7451 {
7452 // 16 pixel buffer to account for slopes that are on bordering screens.
7453
4/8
✓ Branch 0 taken 12220 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12220 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12220 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 12220 times.
12220 if(x<0 || y<0 || x>=world_w+16 || y>=world_h+16)
7454 return true;
7455
7456 // for(int32_t i=0; i<4; i++)
7457
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12220 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12220 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7458 return true;
7459
7460
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12220 times.
12220 if (collide_object(x, y,cnt*8, 1, ign))
7461 return true;
7462
7463 12220 return _walkflag(x,y,cnt);
7464 12220 }
7465
7466 39594 void map_bkgsfx(bool on)
7467 {
7468
2/2
✓ Branch 0 taken 39573 times.
✓ Branch 1 taken 21 times.
39594 if(on)
7469 {
7470 39573 cont_sfx(hero_scr->oceansfx);
7471
7472
4/4
✓ Branch 0 taken 369 times.
✓ Branch 1 taken 39204 times.
✓ Branch 2 taken 315 times.
✓ Branch 3 taken 54 times.
39573 if(hero_scr->bosssfx && !(game->lvlitems[dlevel]&(1 << li_boss_killed)))
7473 315 cont_sfx(hero_scr->bosssfx);
7474 39573 }
7475 else
7476 {
7477 21 adjust_sfx(hero_scr->oceansfx,128,false);
7478 21 adjust_sfx(hero_scr->bosssfx,128,false);
7479
7480
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 21 times.
135 for(int32_t i=0; i<guys.Count(); i++)
7481 {
7482
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 84 times.
114 if(((enemy*)guys.spr(i))->bgsfx)
7483 84 stop_sfx(((enemy*)guys.spr(i))->bgsfx);
7484 114 }
7485 }
7486 39594 }
7487
7488 261 void toggle_switches(dword flags, bool entry)
7489 {
7490
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 261 times.
261 if(!flags) return; //No flags to toggle
7491
7492 522 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7493 261 toggle_switches(flags, entry, create_screen_handles(scr));
7494 261 });
7495 261 }
7496 55210 void toggle_switches(dword flags, bool entry, const screen_handles_t& screen_handles)
7497 {
7498
2/2
✓ Branch 0 taken 931 times.
✓ Branch 1 taken 54279 times.
55210 if(!flags) return; //No flags to toggle
7499
7500 931 mapscr* m = screen_handles[0].base_scr;
7501 931 int screen = m->screen;
7502 931 bool is_active_screen = is_in_current_region(m);
7503
7504 525235 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
7505 524304 byte togglegrid[176] = {0};
7506 524304 mapscr* scr = rpos_handle.scr;
7507 524304 int lyr = rpos_handle.layer;
7508 524304 int pos = rpos_handle.pos;
7509 524304 newcombo const& cmb = combobuf[scr->data[pos]];
7510
2/2
✓ Branch 0 taken 39424 times.
✓ Branch 1 taken 484880 times.
524304 if(is_active_screen)
7511
1/2
✓ Branch 0 taken 484880 times.
✗ Branch 1 not taken.
641011 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7512
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 156131 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
156131 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7513 }, ctrigSWITCHSTATE);
7514
3/4
✓ Branch 0 taken 523592 times.
✓ Branch 1 taken 712 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2809 times.
524304 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && unsigned(cmb.c_attributes[8].getTrunc()) < 32
7515
2/2
✓ Branch 0 taken 2809 times.
✓ Branch 1 taken 521495 times.
524304 && !(cmb.usrflags & cflag11)) //global state
7516 {
7517
2/2
✓ Branch 0 taken 446 times.
✓ Branch 1 taken 2363 times.
2809 if(flags&(1<<cmb.c_attributes[8].getTrunc()))
7518 {
7519 2363 set<int32_t> oldData;
7520 //Increment the combo/cset by the attributes
7521 2363 int32_t cmbofs = cmb.c_attributes[0].getTrunc();
7522 2363 int32_t csofs = cmb.c_attributes[1].getTrunc();
7523
1/2
✓ Branch 0 taken 2363 times.
✗ Branch 1 not taken.
2363 oldData.insert(scr->data[pos]);
7524
1/2
✓ Branch 0 taken 2363 times.
✗ Branch 1 not taken.
2363 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7525 2363 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7526
4/4
✓ Branch 0 taken 1444 times.
✓ Branch 1 taken 919 times.
✓ Branch 2 taken 1206 times.
✓ Branch 3 taken 238 times.
2363 if(entry && (cmb.usrflags&cflag8))
7527 {
7528 238 newcombo const* tmp = &combobuf[scr->data[pos]];
7529
2/4
✓ Branch 0 taken 238 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 238 times.
✗ Branch 3 not taken.
238 while(tmp->can_cycle())
7530 {
7531 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7532 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7533 if(oldData.find(cid) != oldData.end())
7534 break;
7535
7536 scr->data[pos] = cid;
7537 if(!(tmp->animflags & AF_CYCLENOCSET))
7538 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7539 oldData.insert(cid);
7540 tmp = &combobuf[cid];
7541 }
7542 238 }
7543 2363 int32_t cmbid = scr->data[pos];
7544
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 2322 times.
2363 if(combobuf[cmbid].animflags & AF_CYCLE)
7545 {
7546 41 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7547 41 combobuf[cmbid].cur_frame=0;
7548 41 combobuf[cmbid].aclk = 0;
7549
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 combo_caches::drawing.refresh(cmbid);
7550 41 }
7551 2363 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7552
2/2
✓ Branch 0 taken 560 times.
✓ Branch 1 taken 1803 times.
2363 if(cmb.type == cCSWITCH) return; //Switches don't toggle other layers
7553
2/2
✓ Branch 0 taken 12621 times.
✓ Branch 1 taken 1803 times.
14424 for(int32_t lyr2 = 0; lyr2 < 7; ++lyr2) //Toggle same pos on other layers, if flag set
7554 {
7555
2/2
✓ Branch 0 taken 1803 times.
✓ Branch 1 taken 10818 times.
12621 if(lyr==lyr2) continue;
7556
2/2
✓ Branch 0 taken 344 times.
✓ Branch 1 taken 10474 times.
10818 if(!(cmb.usrflags&(1<<lyr2))) continue;
7557
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
344 if(togglegrid[pos]&(1<<lyr2)) continue;
7558
7559 344 mapscr* scr_2 = screen_handles[lyr2].scr;
7560
2/4
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 344 times.
344 if(!scr_2 || !scr_2->data[pos]) //Don't increment empty space
7561 continue;
7562 344 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7563
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
344 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK) && !(cmb.usrflags & cflag11)
7564 && unsigned(cmb_2.c_attributes[8].getTrunc()) < 32 && (flags&(1<<cmb_2.c_attributes[8].getTrunc())))
7565 continue; //This is a switch/block that will be hit later in the loop!
7566 344 set<int32_t> oldData2;
7567 //Increment the combo/cset by the original cmb's attributes
7568
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 oldData2.insert(scr_2->data[pos]);
7569
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7570 344 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7571
3/4
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 294 times.
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
344 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7572 {
7573 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7574 while(tmp->can_cycle())
7575 {
7576 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7577 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7578 if(oldData2.find(cid) != oldData2.end())
7579 break;
7580
7581 scr_2->data[pos] = cid;
7582 if(!(tmp->animflags & AF_CYCLENOCSET))
7583 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7584 oldData2.insert(cid);
7585 tmp = &combobuf[cid];
7586 }
7587 }
7588 344 int32_t cmbid2 = scr_2->data[pos];
7589
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
344 if(combobuf[cmbid2].animflags & AF_CYCLE)
7590 {
7591 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7592 combobuf[cmbid2].cur_frame=0;
7593 combobuf[cmbid2].aclk = 0;
7594 combo_caches::drawing.refresh(cmbid2);
7595 }
7596 344 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7597 344 }
7598
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 560 times.
✓ Branch 2 taken 1803 times.
2363 }
7599 2249 }
7600 524304 });
7601
7602
3/4
✓ Branch 0 taken 519 times.
✓ Branch 1 taken 412 times.
✓ Branch 2 taken 519 times.
✗ Branch 3 not taken.
931 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7603 {
7604 newcombo const& cmb = combobuf[mblock2.bcombo];
7605 if(!(cmb.usrflags & cflag11) && (cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && unsigned(cmb.c_attributes[8].getTrunc()) < 32)
7606 {
7607 if(flags&(1<<cmb.c_attributes[8].getTrunc()))
7608 {
7609 //Increment the combo/cset by the attributes
7610 int32_t cmbofs = cmb.c_attributes[0].getTrunc();
7611 int32_t csofs = cmb.c_attributes[1].getTrunc();
7612 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7613 mblock2.cs = (mblock2.cs + csofs) & 15;
7614 int32_t cmbid = mblock2.bcombo;
7615 if(combobuf[cmbid].animflags & AF_CYCLE)
7616 {
7617 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7618 combobuf[cmbid].cur_frame=0;
7619 combobuf[cmbid].aclk = 0;
7620 combo_caches::drawing.refresh(cmbid);
7621 }
7622 }
7623 }
7624 }
7625
7626
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 707 times.
931 if (is_active_screen)
7627 {
7628 707 int screen_index_offset = get_region_screen_offset(m->screen);
7629 707 word c = m->numFFC();
7630
2/2
✓ Branch 0 taken 565 times.
✓ Branch 1 taken 707 times.
1272 for (int q = 0; q < c; ++q)
7631 {
7632 565 auto ffc_handle = *m->getFFCHandle(q, screen_index_offset);
7633
1/2
✓ Branch 0 taken 565 times.
✗ Branch 1 not taken.
596 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7634
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
31 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7635 }, ctrigSWITCHSTATE);
7636 565 }
7637 707 }
7638 55210 }
7639
7640 1 void toggle_gswitches(int32_t state, bool entry)
7641 {
7642 2 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7643 1 toggle_gswitches(state, entry, create_screen_handles(scr));
7644 1 });
7645 1 }
7646 1 void toggle_gswitches(int32_t state, bool entry, const screen_handles_t& screen_handles)
7647 {
7648 1 bool states[256] = {false};
7649 1 states[state] = true;
7650 1 toggle_gswitches(states, entry, screen_handles);
7651 1 }
7652 15796706 void toggle_gswitches(bool* states, bool entry, const screen_handles_t& screen_handles)
7653 {
7654
1/2
✓ Branch 0 taken 15796706 times.
✗ Branch 1 not taken.
15796706 if(!states) return;
7655
7656 15796706 auto& combo_cache = combo_caches::gswitch;
7657 15796706 mapscr* base_scr = screen_handles[0].base_scr;
7658 15796706 int screen = base_scr->screen;
7659 15796706 bool is_active_screen = is_in_current_region(base_scr);
7660 15796706 byte togglegrid[176] = {0};
7661
2/2
✓ Branch 0 taken 15796706 times.
✓ Branch 1 taken 110576942 times.
126373648 for(int32_t lyr = 0; lyr <= 6; ++lyr)
7662 {
7663 110576942 mapscr* scr = screen_handles[lyr].scr;
7664
2/2
✓ Branch 0 taken 74675802 times.
✓ Branch 1 taken 35901140 times.
110576942 if (!scr)
7665 74675802 continue;
7666
7667
2/2
✓ Branch 0 taken 6318600640 times.
✓ Branch 1 taken 35901140 times.
6354501780 for(int32_t pos = 0; pos < 176; ++pos)
7668 {
7669 6318600640 int cid = scr->data[pos];
7670 6318600640 auto& mini_cmb = combo_cache.minis[cid];
7671
7672
2/2
✓ Branch 0 taken 2910336 times.
✓ Branch 1 taken 6315690304 times.
6318600640 if (is_active_screen)
7673 {
7674
2/2
✓ Branch 0 taken 6315688422 times.
✓ Branch 1 taken 1882 times.
6315690304 if (mini_cmb.trigger_global_state)
7675 {
7676 1882 auto rpos_handle = get_rpos_handle_for_screen(screen, lyr, pos);
7677
1/2
✓ Branch 0 taken 1882 times.
✗ Branch 1 not taken.
3764 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7678
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1882 times.
1882 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7679 }, ctrigSWITCHSTATE);
7680 1882 }
7681 6315690304 }
7682
7683
2/2
✓ Branch 0 taken 55356 times.
✓ Branch 1 taken 6318545284 times.
6318600640 if (!mini_cmb.has_global_state)
7684 6318545284 continue;
7685
7686 55356 newcombo const& cmb = combobuf[cid];
7687
2/4
✓ Branch 0 taken 55356 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 55356 times.
55356 if(cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK)
7688 {
7689 uint state_idx = cmb.c_attributes[8].getTrunc();
7690 if(state_idx < 256 && states[state_idx])
7691 {
7692 set<int32_t> oldData;
7693 //Increment the combo/cset by the attributes
7694 int32_t cmbofs = cmb.c_attributes[0].getTrunc();
7695 int32_t csofs = cmb.c_attributes[1].getTrunc();
7696 oldData.insert(scr->data[pos]);
7697 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7698 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7699 if(entry && (cmb.usrflags&cflag8))
7700 {
7701 newcombo const* tmp = &combobuf[scr->data[pos]];
7702 while(tmp->can_cycle())
7703 {
7704 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7705 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7706 if(oldData.find(cid) != oldData.end())
7707 break;
7708 scr->data[pos] = cid;
7709 if(!(tmp->animflags & AF_CYCLENOCSET))
7710 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7711 oldData.insert(cid);
7712 tmp = &combobuf[cid];
7713 }
7714 }
7715 int32_t cmbid = scr->data[pos];
7716 if(combobuf[cmbid].animflags & AF_CYCLE)
7717 {
7718 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7719 combobuf[cmbid].cur_frame=0;
7720 combobuf[cmbid].aclk = 0;
7721 combo_caches::drawing.refresh(cmbid);
7722 }
7723 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7724 if(cmb.type == cCSWITCH) continue; //Switches don't toggle other layers
7725 for(int32_t lyr2 = 0; lyr2 <= 6; ++lyr2) //Toggle same pos on other layers, if flag set
7726 {
7727 if(lyr==lyr2) continue;
7728 if(!(cmb.usrflags&(1<<lyr2))) continue;
7729 if(togglegrid[pos]&(1<<lyr2)) continue;
7730 mapscr* scr_2 = lyr2 == 0 ? base_scr : get_scr_layer_valid(screen, lyr2);
7731 if(!scr_2 || !scr_2->data[pos]) //Don't increment empty space
7732 continue;
7733 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7734 uint state_idx = cmb_2.c_attributes[8].getTrunc();
7735 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK)
7736 && (cmb_2.usrflags & cflag11) && (state_idx < 256 && states[state_idx]))
7737 continue; //This is a switch/block that will be hit later in the loop!
7738 set<int32_t> oldData2;
7739 //Increment the combo/cset by the original cmb's attributes
7740 oldData2.insert(scr_2->data[pos]);
7741 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7742 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7743 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7744 {
7745 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7746 while(tmp->can_cycle())
7747 {
7748 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7749 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7750 if(oldData2.find(cid) != oldData2.end())
7751 break;
7752 scr_2->data[pos] = cid;
7753 if(!(tmp->animflags & AF_CYCLENOCSET))
7754 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7755 oldData2.insert(cid);
7756 tmp = &combobuf[cid];
7757 }
7758 }
7759 int32_t cmbid2 = scr_2->data[pos];
7760 if(combobuf[cmbid2].animflags & AF_CYCLE)
7761 {
7762 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7763 combobuf[cmbid2].cur_frame=0;
7764 combobuf[cmbid2].aclk = 0;
7765 combo_caches::drawing.refresh(cmbid2);
7766 }
7767 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7768 }
7769 }
7770 }
7771 55356 }
7772 35901140 }
7773
7774
4/4
✓ Branch 0 taken 554531 times.
✓ Branch 1 taken 15242175 times.
✓ Branch 2 taken 549787 times.
✓ Branch 3 taken 4744 times.
15796706 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7775 {
7776 4744 newcombo const& cmb = combobuf[mblock2.bcombo];
7777
2/4
✓ Branch 0 taken 4744 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4744 times.
✗ Branch 3 not taken.
4744 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && (cmb.usrflags & cflag11))
7778 {
7779 uint state_idx = cmb.c_attributes[8].getTrunc();
7780 if(state_idx < 256 && states[state_idx])
7781 {
7782 //Increment the combo/cset by the attributes
7783 int32_t cmbofs = cmb.c_attributes[0].getTrunc();
7784 int32_t csofs = cmb.c_attributes[1].getTrunc();
7785 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7786 mblock2.cs = (mblock2.cs + csofs) & 15;
7787 int32_t cmbid = mblock2.bcombo;
7788 if(combobuf[cmbid].animflags & AF_CYCLE)
7789 {
7790 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7791 combobuf[cmbid].cur_frame=0;
7792 combobuf[cmbid].aclk = 0;
7793 combo_caches::drawing.refresh(cmbid);
7794 }
7795 }
7796 }
7797 4744 }
7798
7799
2/2
✓ Branch 0 taken 16159 times.
✓ Branch 1 taken 15780547 times.
15796706 if(is_active_screen)
7800 {
7801 15780547 int screen_index_offset = get_region_screen_offset(screen);
7802 15780547 word c = base_scr->numFFC();
7803
2/2
✓ Branch 0 taken 455562886 times.
✓ Branch 1 taken 15780547 times.
471343433 for (int q = 0; q < c; ++q)
7804 {
7805 455562886 auto ffc_handle = *base_scr->getFFCHandle(q, screen_index_offset);
7806
1/2
✓ Branch 0 taken 455562886 times.
✗ Branch 1 not taken.
455796224 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7807
1/2
✓ Branch 0 taken 233338 times.
✗ Branch 1 not taken.
233338 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7808 }, ctrigSWITCHSTATE);
7809 455562886 }
7810 15780547 }
7811 15796706 }
7812 54949 void toggle_gswitches_load(const screen_handles_t& screen_handles)
7813 {
7814 bool states[256];
7815
2/2
✓ Branch 0 taken 14066944 times.
✓ Branch 1 taken 54949 times.
14121893 for(auto q = 0; q < 256; ++q)
7816 {
7817 14066944 states[q] = game->gswitch_timers[q] != 0;
7818 14066944 }
7819 54949 toggle_gswitches(states, true, screen_handles);
7820 54949 }
7821 15352388 void run_gswitch_timers()
7822 {
7823 15352388 bool states[256] = {false};
7824 15352388 auto& m = game->gswitch_timers.mut_inner();
7825
2/2
✓ Branch 0 taken 3926112512 times.
✓ Branch 1 taken 15352388 times.
3941464900 for(auto it = m.begin(); it != m.end();)
7826 {
7827
2/2
✓ Branch 0 taken 3926111912 times.
✓ Branch 1 taken 600 times.
3926112512 if(it->second > 0)
7828
2/2
✓ Branch 0 taken 599 times.
✓ Branch 1 taken 1 times.
600 if(!--it->second)
7829 {
7830 1 states[it->first] = true;
7831 1 it = m.erase(it);
7832 1 continue;
7833 }
7834 3926112511 ++it;
7835 }
7836 31094144 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7837 15741756 toggle_gswitches(states, false, create_screen_handles(scr));
7838 15741756 });
7839 15352388 }
7840 1154 void onload_gswitch_timers() //Reset all timers that were counting down, no trigger necessary
7841 {
7842
2/2
✓ Branch 0 taken 295424 times.
✓ Branch 1 taken 1154 times.
296578 for(auto q = 0; q < 256; ++q)
7843 {
7844
1/2
✓ Branch 0 taken 295424 times.
✗ Branch 1 not taken.
295424 if(game->gswitch_timers[q] > 0)
7845 game->gswitch_timers[q] = 0;
7846 295424 }
7847 1154 }
7848
7849 /**** View Map ****/
7850
7851 int32_t mapres = 0;
7852 int32_t view_map_show_mode = 3;
7853
7854 129280 bool displayOnMap(int32_t x, int32_t y)
7855 {
7856 129280 int32_t s = (y<<4) + x;
7857 129280 int mi = mapind(cur_map, s);
7858
2/2
✓ Branch 0 taken 70863 times.
✓ Branch 1 taken 58417 times.
129280 if (!(game->maps[mi]&mVISITED))
7859 70863 return false;
7860
7861 // Don't display if not part of DMap
7862
4/4
✓ Branch 0 taken 15807 times.
✓ Branch 1 taken 42610 times.
✓ Branch 2 taken 4750 times.
✓ Branch 3 taken 4311 times.
67478 if(((DMaps[cur_dmap].flags&dmfDMAPMAP) &&
7863
1/2
✓ Branch 0 taken 15807 times.
✗ Branch 1 not taken.
15807 (DMaps[cur_dmap].type != dmOVERW) &&
7864
2/2
✓ Branch 0 taken 12631 times.
✓ Branch 1 taken 3176 times.
15807 !(x >= DMaps[cur_dmap].xoff &&
7865
2/2
✓ Branch 0 taken 9061 times.
✓ Branch 1 taken 3570 times.
12631 x < DMaps[cur_dmap].xoff+8 &&
7866 9061 DMaps[cur_dmap].grid[y]&(128>>(x-DMaps[cur_dmap].xoff)))))
7867 11057 return false;
7868 else
7869 47360 return true;
7870 129280 }
7871
7872 1010 void ViewMap()
7873 {
7874 1010 ViewingMap = true;
7875
7876 1010 BITMAP* mappic = NULL;
7877 static double scales[17] =
7878 {
7879 0.03125, 0.04419, 0.0625, 0.08839, 0.125, 0.177, 0.25, 0.3535,
7880 0.50, 0.707, 1.0, 1.414, 2.0, 2.828, 4.0, 5.657, 8.0
7881 };
7882
7883 // Cursor position for hero, in absolute map coordinates.
7884 1010 int32_t lx = ((cur_screen & 15) << 8) + HeroX() + 8;
7885 1010 int32_t ly = ((cur_screen >> 4) * 176) + HeroY() + 8;
7886
7887 int32_t px;
7888 int32_t py;
7889
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1010 times.
1010 if (is_in_scrolling_region())
7890 {
7891 // Center the player on the middle of the map view.
7892 px = (16*256/2 - lx) * 2;
7893 py = (8*176/2 - ly) * 2;
7894 }
7895 else
7896 {
7897 // Center the current screen on the middle of the map view.
7898 1010 px = ((8-(cur_screen&15)) << 9) - 256;
7899 1010 py = ((4-(cur_screen>>4)) * 352) - 176;
7900 }
7901
7902 1010 int32_t sc = 6;
7903
7904 1010 bool done=false, redraw=true;
7905
7906 1010 mappic = create_bitmap_ex(8,(256*16)>>mapres,(176*8)>>mapres);
7907
7908
1/2
✓ Branch 0 taken 1010 times.
✗ Branch 1 not taken.
1010 if(!mappic)
7909 {
7910 enter_sys_pal();
7911 displayinfo("View Map","Not enough memory.");
7912 exit_sys_pal();
7913 return;
7914 }
7915
7916 1010 clear_to_color(mappic, WHITE);
7917
7918 1010 auto prev_viewport = viewport;
7919 1010 viewport.x = 0;
7920 1010 viewport.y = 0;
7921
7922 // draw the map
7923 1010 BITMAP* screen_bmp = create_bitmap_ex(8, 256, 176);
7924 1010 combotile_add_x = 256;
7925 1010 combotile_add_y = 0;
7926 1010 bool classic_draw = get_qr(qr_CLASSIC_DRAWING_ORDER);
7927
2/2
✓ Branch 0 taken 8080 times.
✓ Branch 1 taken 1010 times.
9090 for(int32_t y=0; y<8; y++)
7928 {
7929
2/2
✓ Branch 0 taken 8080 times.
✓ Branch 1 taken 129280 times.
137360 for(int32_t x=0; x<16; x++)
7930 {
7931
2/2
✓ Branch 0 taken 47360 times.
✓ Branch 1 taken 81920 times.
129280 if (!displayOnMap(x, y))
7932 81920 continue;
7933
7934 47360 int screen = map_scr_xy_to_index(x, y);
7935 47360 auto scrs = loadscr2(screen);
7936 47360 mapscr* scr = &scrs[0];
7937
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 if (!scr->is_valid())
7938 continue;
7939
7940 screen_handles_t screen_handles;
7941
2/2
✓ Branch 0 taken 47360 times.
✓ Branch 1 taken 331520 times.
378880 for (int i = 0; i <= 6; i++)
7942
3/4
✓ Branch 0 taken 331520 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 114582 times.
✓ Branch 3 taken 216938 times.
331520 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
7943
7944 47360 int xx = 0;
7945 47360 int yy = -playing_field_offset;
7946
7947
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 if (!classic_draw)
7948 for (int layer = -7; layer <= -4; ++layer)
7949 do_ffc_layer(screen_bmp, layer, screen_handles[0], xx, yy);
7950
7951
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 if(classic_draw)
7952 {
7953
2/2
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 47313 times.
47360 if(XOR(scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
7954
1/2
✓ Branch 0 taken 47 times.
✗ Branch 1 not taken.
47 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7955
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7956 47360 }
7957
7958
2/2
✓ Branch 0 taken 213 times.
✓ Branch 1 taken 47147 times.
47360 if(XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
7959
1/2
✓ Branch 0 taken 213 times.
✗ Branch 1 not taken.
213 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7960
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, -3, screen_handles[0], xx, yy);
7961
7962
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 47360 times.
47360 if(!classic_draw)
7963 {
7964 if(XOR(scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
7965 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7966 do_ffc_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7967 do_ffc_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7968 }
7969
7970
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 if(lenscheck(scr,0)) putscr(scr, screen_bmp, 0, 0);
7971
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 0, screen_handles[0], xx, yy);
7972
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[1], xx, yy);
7973
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 1, screen_handles[0], xx, yy);
7974
7975
2/2
✓ Branch 0 taken 47313 times.
✓ Branch 1 taken 47 times.
47360 if(!XOR((scr->flags7&fLAYER2BG), DMaps[cur_dmap].flags&dmfLAYER2BG))
7976 {
7977
1/2
✓ Branch 0 taken 47313 times.
✗ Branch 1 not taken.
47313 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7978
1/2
✓ Branch 0 taken 47313 times.
✗ Branch 1 not taken.
47313 do_ffc_layer(screen_bmp, 2, screen_handles[0], xx, yy);
7979 47313 }
7980
7981
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 putscrdoors(scr, screen_bmp, xx, yy);
7982
2/2
✓ Branch 0 taken 43358 times.
✓ Branch 1 taken 4002 times.
47360 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
7983 {
7984
1/2
✓ Branch 0 taken 43358 times.
✗ Branch 1 not taken.
43358 do_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7985
2/2
✓ Branch 0 taken 3462 times.
✓ Branch 1 taken 39896 times.
43358 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
7986 {
7987
1/2
✓ Branch 0 taken 3462 times.
✗ Branch 1 not taken.
3462 do_layer(screen_bmp,-2, screen_handles[1], xx, yy);
7988
1/2
✓ Branch 0 taken 3462 times.
✗ Branch 1 not taken.
3462 do_layer(screen_bmp,-2, screen_handles[2], xx, yy);
7989 3462 }
7990 43358 }
7991
7992
2/2
✓ Branch 0 taken 47147 times.
✓ Branch 1 taken 213 times.
47360 if(!XOR((scr->flags7&fLAYER3BG), DMaps[cur_dmap].flags&dmfLAYER3BG))
7993 {
7994
1/2
✓ Branch 0 taken 47147 times.
✗ Branch 1 not taken.
47147 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7995
1/2
✓ Branch 0 taken 47147 times.
✗ Branch 1 not taken.
47147 do_ffc_layer(screen_bmp, 3, screen_handles[0], xx, yy);
7996 47147 }
7997
7998
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[4], xx, yy);
7999
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 4, screen_handles[0], xx, yy);
8000
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, -1, screen_handles[0], xx, yy);
8001
2/2
✓ Branch 0 taken 7464 times.
✓ Branch 1 taken 39896 times.
47360 if(get_qr(qr_OVERHEAD_COMBOS_L1_L2))
8002 {
8003
1/2
✓ Branch 0 taken 7464 times.
✗ Branch 1 not taken.
7464 do_layer(screen_bmp,-1, screen_handles[1], xx, yy);
8004
1/2
✓ Branch 0 taken 7464 times.
✗ Branch 1 not taken.
7464 do_layer(screen_bmp,-1, screen_handles[2], xx, yy);
8005 7464 }
8006
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[5], xx, yy);
8007
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 5, screen_handles[0], xx, yy);
8008
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1680 times.
✓ Branch 3 taken 45680 times.
47360 if(replay_version_check(40))
8009
1/2
✓ Branch 0 taken 1680 times.
✗ Branch 1 not taken.
1680 do_ffc_layer(screen_bmp, -1000, screen_handles[0], xx, yy);
8010
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[6], xx, yy);
8011
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 6, screen_handles[0], xx, yy);
8012
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 7, screen_handles[0], xx, yy);
8013
8014
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 stretch_blit(screen_bmp, mappic, 0, 0, 256, 176, x<<(8-mapres), (y*176)>>mapres, 256>>mapres, 176>>mapres);
8015
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
47360 }
8016 8080 }
8017
8018 1010 viewport = prev_viewport;
8019 1010 combotile_add_x = 0;
8020 1010 combotile_add_y = 0;
8021
8022 1010 destroy_bitmap(screen_bmp);
8023 1010 clear_keybuf();
8024 1010 pause_all_sfx();
8025
8026 // view it
8027 1010 int32_t delay = 0;
8028
8029 1010 do
8030 {
8031
2/2
✓ Branch 0 taken 189085 times.
✓ Branch 1 taken 29891 times.
218976 if (replay_version_check(0, 11))
8032 29891 load_control_state();
8033
8034 218976 int32_t step = int32_t(16.0/scales[sc]);
8035 218976 step = (step>>1) + (step&1);
8036 218976 bool r = getInput(btnR);
8037
8038
1/2
✓ Branch 0 taken 218976 times.
✗ Branch 1 not taken.
218976 if(getInput(btnL))
8039 {
8040 step <<= 2;
8041 delay = 0;
8042 }
8043
8044
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 218976 times.
218976 if(r)
8045 {
8046 if(getInput(btnUp, INPUT_PRESS))
8047 {
8048 py+=step;
8049 redraw=true;
8050 }
8051
8052 if(getInput(btnDown, INPUT_PRESS))
8053 {
8054 py-=step;
8055 redraw=true;
8056 }
8057
8058 if(getInput(btnLeft, INPUT_PRESS))
8059 {
8060 px+=step;
8061 redraw=true;
8062 }
8063
8064 if(getInput(btnRight, INPUT_PRESS))
8065 {
8066 px-=step;
8067 redraw=true;
8068 }
8069 }
8070 else
8071 {
8072
2/2
✓ Branch 0 taken 203528 times.
✓ Branch 1 taken 15448 times.
218976 if(getInput(btnUp))
8073 {
8074 15448 py+=step;
8075 15448 redraw=true;
8076 15448 }
8077
8078
2/2
✓ Branch 0 taken 203410 times.
✓ Branch 1 taken 15566 times.
218976 if(getInput(btnDown))
8079 {
8080 15566 py-=step;
8081 15566 redraw=true;
8082 15566 }
8083
8084
2/2
✓ Branch 0 taken 191540 times.
✓ Branch 1 taken 27436 times.
218976 if(getInput(btnLeft))
8085 {
8086 27436 px+=step;
8087 27436 redraw=true;
8088 27436 }
8089
8090
2/2
✓ Branch 0 taken 192194 times.
✓ Branch 1 taken 26782 times.
218976 if(getInput(btnRight))
8091 {
8092 26782 px-=step;
8093 26782 redraw=true;
8094 26782 }
8095 }
8096
8097
2/2
✓ Branch 0 taken 22044 times.
✓ Branch 1 taken 196932 times.
218976 if(delay)
8098 22044 --delay;
8099 else
8100 {
8101 196932 bool a = getInput(btnA);
8102 196932 bool b = getInput(btnB);
8103
8104
3/4
✓ Branch 0 taken 1786 times.
✓ Branch 1 taken 195146 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1786 times.
196932 if(a && !b)
8105 {
8106
1/2
✓ Branch 0 taken 1786 times.
✗ Branch 1 not taken.
1786 sc=zc_min(sc+1,16);
8107 1786 delay=8;
8108 1786 redraw=true;
8109 1786 }
8110
8111
3/4
✓ Branch 0 taken 972 times.
✓ Branch 1 taken 195960 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 972 times.
196932 if(b && !a)
8112 {
8113
2/2
✓ Branch 0 taken 971 times.
✓ Branch 1 taken 1 times.
972 sc=zc_max(sc-1,0);
8114 972 delay=8;
8115 972 redraw=true;
8116 972 }
8117 }
8118
8119
2/2
✓ Branch 0 taken 218965 times.
✓ Branch 1 taken 11 times.
218976 if(getInput(btnP, INPUT_PRESS))
8120 11 --view_map_show_mode;
8121
8122 218976 px = vbound(px,-4096,4096);
8123 218976 py = vbound(py,-1408,1408);
8124
8125 218976 double scale = scales[sc];
8126
8127
2/2
✓ Branch 0 taken 75341 times.
✓ Branch 1 taken 143635 times.
218976 if(!redraw)
8128 {
8129 143635 blit(scrollbuf_old,framebuf,256,0,0,0,256,232);
8130 143635 }
8131 else
8132 {
8133 75341 clear_to_color(framebuf,BLACK);
8134 150682 stretch_blit(mappic,framebuf,0,0,mappic->w,mappic->h,
8135 75341 int32_t(256+(int64_t(px)-mappic->w)*scale)/2,int32_t(224+(int64_t(py)-mappic->h)*scale)/2,
8136 75341 int32_t(mappic->w*scale),int32_t(mappic->h*scale));
8137
8138 75341 blit(framebuf,scrollbuf_old,0,0,256,0,256,232);
8139 75341 redraw=false;
8140 }
8141
8142 218976 int32_t x = int32_t(256+(px-((2048-int64_t(lx))*2))*scale)/2;
8143 218976 int32_t y = int32_t(224+(py-((704-int64_t(ly))*2))*scale)/2;
8144
8145
2/2
✓ Branch 0 taken 7466 times.
✓ Branch 1 taken 211510 times.
218976 if(view_map_show_mode&1)
8146 {
8147 211510 line(framebuf,x-7,y-7,x+7,y+7,(frame&3)+252);
8148 211510 line(framebuf,x+7,y-7,x-7,y+7,(frame&3)+252);
8149 211510 }
8150
8151
3/4
✓ Branch 0 taken 5600 times.
✓ Branch 1 taken 213376 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5600 times.
218976 if(view_map_show_mode&2 || r)
8152 213376 textprintf_ex(framebuf,font,224,216,WHITE,BLACK,"%1.2f",scale);
8153
8154
1/2
✓ Branch 0 taken 218976 times.
✗ Branch 1 not taken.
218976 if(r)
8155 {
8156 textprintf_ex(framebuf,font,0,208,WHITE,BLACK,"m: %d %d",px,py);
8157 textprintf_ex(framebuf,font,0,216,WHITE,BLACK,"x: %d %d",x,y);
8158 }
8159
8160 218976 advanceframe(false, false);
8161
2/2
✓ Branch 0 taken 29891 times.
✓ Branch 1 taken 189085 times.
218976 if (replay_version_check(11))
8162 189085 load_control_state();
8163
8164
2/2
✓ Branch 0 taken 217967 times.
✓ Branch 1 taken 1009 times.
218976 if (getInput(btnS, INPUT_PRESS | INPUT_IGNORE_DISABLE))
8165 1009 done = true;
8166
8167
2/2
✓ Branch 0 taken 217966 times.
✓ Branch 1 taken 1010 times.
437952 }
8168
2/2
✓ Branch 0 taken 1009 times.
✓ Branch 1 taken 217967 times.
218976 while(!done && !Quit);
8169
8170 1010 ViewingMap = false;
8171 1010 destroy_bitmap(mappic);
8172 1010 resume_all_sfx();
8173 1010 }
8174
8175 1112 int32_t onViewMap()
8176 {
8177
4/6
✓ Branch 0 taken 1112 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1112 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 102 times.
✓ Branch 5 taken 1010 times.
1112 if(Playing && cur_screen<128 && DMaps[cur_dmap].flags&dmfVIEWMAP)
8178 {
8179 1010 clear_to_color(framebuf,BLACK);
8180 1010 textout_centre_ex(framebuf,font,"Drawing map...",128,108,WHITE,BLACK);
8181 1010 advanceframe(true);
8182 1010 ViewMap();
8183 1010 }
8184
8185 1112 return D_O_K;
8186 }
8187
8188 38958614 bool isGrassType(int32_t type)
8189 {
8190
2/2
✓ Branch 0 taken 38200501 times.
✓ Branch 1 taken 758113 times.
38958614 switch(type)
8191 {
8192 case cTALLGRASS:
8193 case cTALLGRASSNEXT:
8194 case cTALLGRASSTOUCHY:
8195 758113 return true;
8196 }
8197
8198 38200501 return false;
8199 38958614 }
8200
8201 25672 bool isFlowersType(int32_t type)
8202 {
8203
2/2
✓ Branch 0 taken 21332 times.
✓ Branch 1 taken 4340 times.
25672 switch(type)
8204 {
8205 case cFLOWERS:
8206 case cFLOWERSTOUCHY:
8207 4340 return true;
8208 }
8209
8210 21332 return false;
8211 25672 }
8212
8213 bool isGenericType(int32_t type)
8214 {
8215 switch(type)
8216 {
8217 case cTRIGGERGENERIC:
8218 return true;
8219 }
8220
8221 return false;
8222 }
8223
8224 30978 bool isBushType(int32_t type)
8225 {
8226
2/2
✓ Branch 0 taken 25672 times.
✓ Branch 1 taken 5306 times.
30978 switch(type)
8227 {
8228 case cBUSH:
8229 case cBUSHNEXT:
8230 case cBUSHTOUCHY:
8231 case cBUSHNEXTTOUCHY:
8232
8233 5306 return true;
8234 }
8235
8236 25672 return false;
8237 30978 }
8238
8239 bool isSlashType(int32_t type)
8240 {
8241 switch(type)
8242 {
8243 case cSLASH:
8244 case cSLASHITEM:
8245 case cSLASHTOUCHY:
8246 case cSLASHITEMTOUCHY:
8247 case cSLASHNEXT:
8248 case cSLASHNEXTITEM:
8249 case cSLASHNEXTTOUCHY:
8250 case cSLASHNEXTITEMTOUCHY:
8251 return true;
8252 }
8253
8254 return false;
8255 }
8256
8257 18151 bool isCuttableNextType(int32_t type)
8258 {
8259
2/2
✓ Branch 0 taken 9830 times.
✓ Branch 1 taken 8321 times.
18151 switch(type)
8260 {
8261 case cSLASHNEXT:
8262 case cSLASHNEXTITEM:
8263 case cTALLGRASSNEXT:
8264 case cBUSHNEXT:
8265 case cSLASHNEXTTOUCHY:
8266 case cSLASHNEXTITEMTOUCHY:
8267 case cBUSHNEXTTOUCHY:
8268 8321 return true;
8269 }
8270
8271 9830 return false;
8272 18151 }
8273
8274 20007 bool isTouchyType(int32_t type)
8275 {
8276
2/2
✓ Branch 0 taken 8508 times.
✓ Branch 1 taken 11499 times.
20007 switch(type)
8277 {
8278 case cSLASHTOUCHY:
8279 case cSLASHITEMTOUCHY:
8280 case cBUSHTOUCHY:
8281 case cFLOWERSTOUCHY:
8282 case cTALLGRASSTOUCHY:
8283 case cSLASHNEXTTOUCHY:
8284 case cSLASHNEXTITEMTOUCHY:
8285 case cBUSHNEXTTOUCHY:
8286 11499 return true;
8287 }
8288
8289 8508 return false;
8290 20007 }
8291
8292 38867592 bool isCuttableType(int32_t type)
8293 {
8294
2/2
✓ Branch 0 taken 38414561 times.
✓ Branch 1 taken 453031 times.
38867592 switch(type)
8295 {
8296 case cSLASH:
8297 case cSLASHITEM:
8298 case cBUSH:
8299 case cFLOWERS:
8300 case cTALLGRASS:
8301 case cTALLGRASSNEXT:
8302 case cSLASHNEXT:
8303 case cSLASHNEXTITEM:
8304 case cBUSHNEXT:
8305
8306 case cSLASHTOUCHY:
8307 case cSLASHITEMTOUCHY:
8308 case cBUSHTOUCHY:
8309 case cFLOWERSTOUCHY:
8310 case cTALLGRASSTOUCHY:
8311 case cSLASHNEXTTOUCHY:
8312 case cSLASHNEXTITEMTOUCHY:
8313 case cBUSHNEXTTOUCHY:
8314 453031 return true;
8315 }
8316
8317 38414561 return false;
8318 38867592 }
8319
8320 19783 bool isCuttableItemType(int32_t type)
8321 {
8322
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 19331 times.
19783 switch(type)
8323 {
8324 case cSLASHITEM:
8325 case cBUSH:
8326 case cFLOWERS:
8327 case cTALLGRASS:
8328 case cTALLGRASSNEXT:
8329 case cSLASHNEXTITEM:
8330 case cBUSHNEXT:
8331
8332 case cSLASHITEMTOUCHY:
8333 case cBUSHTOUCHY:
8334 case cFLOWERSTOUCHY:
8335 case cTALLGRASSTOUCHY:
8336 case cSLASHNEXTITEMTOUCHY:
8337 case cBUSHNEXTTOUCHY:
8338 19331 return true;
8339 }
8340
8341 452 return false;
8342 19783 }
8343
8344 69 bool is_push(mapscr* m, int32_t pos)
8345 {
8346
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 if(is_push_flag(m->sflag[pos]))
8347 return true;
8348 69 newcombo const& cmb = combobuf[m->data[pos]];
8349
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 if(is_push_flag(cmb.flag))
8350 return true;
8351
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 55 times.
69 if(cmb.type == cPUSHBLOCK)
8352 14 return true;
8353
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 55 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
55 if(cmb.type == cSWITCHHOOK && (cmb.usrflags&cflag7))
8354 return true; //Counts as 'pushblock' flag
8355 55 return false;
8356 69 }
8357
8358 430 static std::map<int, screen_state_t> screen_states;
8359
8360 37536 std::map<int, screen_state_t>& get_screen_states()
8361 {
8362 37536 return screen_states;
8363 }
8364
8365 45813115 screen_state_t& get_screen_state(int screen)
8366 {
8367 45813115 return screen_states[screen];
8368 }
8369
8370 613 void clear_screen_states()
8371 {
8372 613 screen_states.clear();
8373 613 }
8374
8375 1597 void screen_item_set_state(int screen, ScreenItemState state)
8376 {
8377 1597 get_screen_state(screen).item_state = state;
8378 1597 }
8379
8380 557177 void mark_visited(int screen)
8381 {
8382
2/2
✓ Branch 0 taken 475 times.
✓ Branch 1 taken 556702 times.
557177 if (screen < 0x80)
8383 {
8384
4/4
✓ Branch 0 taken 556685 times.
✓ Branch 1 taken 17 times.
✓ Branch 2 taken 459783 times.
✓ Branch 3 taken 96902 times.
556702 if(!get_qr(qr_ONLY_MARK_SCREENS_VISITED_IF_MAP_VIEWABLE) || (DMaps[cur_dmap].flags&dmfVIEWMAP))
8385 459800 game->maps[mapind(cur_map, screen)] |= mVISITED;
8386
8387 556702 markBmap(-1, screen);
8388 556702 }
8389 557177 }
8390